跑步

在这里插入图片描述
先看一个比较复杂的例子
上面的路线其实可以拆分成几个部分
在这里插入图片描述
可以看到我们将整个路线拆分成了3个环,最外面的环是一个6×5的矩形环 内侧是一个4×3的矩形环,最内侧是一个2×1的矩形环(这已经不是环了)。
每个环对应的步数是好计算的,对于一个n×m的环一共有n×m-4个格子,也就是步数为n×m-4。
在这里插入图片描述

而每个环对应的起点也是显然的,最外层的环起点是(1,1),内层的是(2,2),最内层是(3,3),从最外层数起,第i层的起点是(i,i)。这个起点是必要的准备工作。

对于给定的坐标(x,y),我们是可以知道其在哪一个环上的。假设就在第一层环上,该环为n*m的矩形环,无非就是在最外边的四个边上面,那么一定有 (x==1||x==n||y==1||y==m)为真,否则就应该在里面的某一层。
当判断坐标不在最外层,想要找找看是不是在里面那层时,就接着判断
(x==2||x==n-1||y==2||y==m-1)是否为真
稍微改下就是(x-1==1||x-1==n-2||y-1==1||y-1==m-2),为了方便就这么处理了下。稍微循环几次就能找到坐标在第几层了。
然后知道在第i层之后,我们只要再知道从该层的起点到坐标(x,y)的步数即可。那么问题为在一个左下角的点为(i,i),右上角的点为(n-i+1,m-i+1)构成的矩形环上找一个 (x,y),记下其到(i,i)的步数
在这里插入图片描述

这时可以将整问题的坐标系向左下平移为,在一个左下角的点为(1,1),右上角的点为
(n-2i+2,m-2i+2)构成的矩形环上找一个 (x-i+1,y-i+1)的点,记下其到(1,1)的步数,这就相对而言好算一些。

最后的部分

我们已经将所有的找环上具体位置的问题化简为了如下的问题
在n*m的矩形环上找(x,y)到(1,1)的步数
在这里插入图片描述
y=1时,在最下面的边上,步数:x
x=n时,在最右边的边上,步数:n+y-1
y=m时,在最上面的边上,步数:2n + m - x - 1
x=1时,在最左边的边上,步数:2m + 2n - y - 2
后面两个需要稍微 想下

最终的递归函数

int solve(int n, int m, int x, int y)
{
    if (y == 1)
        return x;
    if (x == n)
        return n + y - 1;
    if (y == m)
        return 2 * n + m - x - 1;
    if (x == 1)
        return 2 * m + 2 * n - y - 2;
    //路线可以化成一个个相互嵌套的环
    // 如果在圈上则会满足上述条件之一,然后根据x,y确定具体位置
    //从而获得步数即可
    return solve(n - 2, m - 2, x - 1, y - 1) + m * 2 + n * 2 - 4;
    //若在不该环上则继续找里面一层的环,并加上该环的步数
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值