Brick Walls

你需要带领一群蚂蚁去寻找食物。 蚂蚁必须通过一堵相当大的砖墙。在砖块表面行走的话,容易被人们发现并被驱赶。如果他们可以通过砖块之间的缝隙行走,这就比较安全。

砖块布局如下图所示。每个砖块都是一个长为2个单位,宽为1个单位距离的矩形。在两块砖之间存在微小的缝隙(水平和垂直两个方向)。

image-20231231090757724.png

蚂蚁一开始在缝隙中的某个点,终点也是在缝隙中的某个点。假设所有砖块都是一样大小,并且是按照有间隙的规则图案排列的,因此这些点总是可以用整数坐标来表示

你的任务是找到可以从起点到终点的最短路径距离。

输入

最多存在 $ 1000 $ 组测试样例。每组测试样例由四个整数组成,其值分别为起始行 $ S_r $ ,起始列 $ S_c $ , 目标行 $ D_r $ , 目标列 $ D_c $ . ( $ 1 \le S_r , S_c, D_r , D_c \le 10^9 $ ) . 最后一行输入将是 "0 0 0 0"--这一行不得作为测试用例处理。

输出

每组测试样例对应一行最短路径距离的输出。

样例输入

1 7 2 7
5 4 3 2
2 3 3 6
0 0 0 0

样例输出

1
4
4

题目分析

目的:求出起止点之间的最短路径距离。

如果考虑将每个坐标视为节点进行建图的话,根据数值范围 $[1,10^9]$,必然是行不通的。且数值那么大考虑是否存在一定的规律。

若砖块都是 $1\times 1$ 大小的那么题目非常简单,直接求曼哈顿距离就可以了。问题在于砖块大小是 $1\times 2$ 的,给求解带来了麻烦。我们设垂直方向的距离为 disx,水平方向的距离为 disy。

画图,仔细观察,可发现只要 disx$\le$disy,那么可以直接求曼哈顿距离 (如下图)。

1703988784428.png

接下来考虑 disx$>$disy。

可发现,砖块的分布是呈周期变化的,且周期大小为 $2$,那么我们在找规律的时候就可以需要结合这个周期去尝试一下。

我们将行走的路线分成两个阶段,一个阶段是能使用曼哈顿距离的部分,一个阶段是不能使用曼哈顿距离的阶段。

对于第二个阶段,又能分两种情况,一是有直接往下走的缝隙,二是没有直接往下走的缝隙。对于情况一的特征判断就是只要起点的横纵坐标奇偶性一致,第一阶段结束了,就有直接往下的道路。否则,就没有属于情况二。

对于数值方向上行走的距离,可发现无论哪种情况,都是坐标差值,难点在于水平位置上需要来回着进行行走。那么观察下不同垂直距离对应的来回行走的距离情况。

1703992026403.png

情况1 情况2
垂直距离来回行走距离垂直距离来回行走距离
$1$$0$$1$$2$
$2$$2$$2$$2$
$3$$2$$3$$4$
$4$$4$$4$$4$
$5$$4$$5$$6$
$6$$6$$6$$6$
$7$$6$$7$$8$
$8$$8$$8$$8$

可发现是呈存在变化规律的,那么分情况进行讨论即可。

代码实现

#include <bits/stdc++.h>
using namespace std;
int sx,sy,fx,fy;
typedef long long ll;
int main()
{
    while(cin>>sx>>sy>>fx>>fy&&(sx||sy||fx||fy)){
        ll disx=abs(sx-fx),disy=abs(sy-fy);
        ll ans=0;
        if(disx<=disy) cout<<disx+disy<<endl;//曼哈顿距离
        else{
            if(sx>fx){//调整位置,保证从上往下
                swap(sx,fx);
                swap(sy,fy);
            }
            ans=disx+disy;//计算阶段1 + 阶段2的垂直部分距离 (disy+disy)+(disx-disy)
            disx-=disy;
            //判断是否属于情况1 坐标奇偶性相同
            if((sx%2!=0&&sy%2!=0)||(sx%2==0&&sy%2==0)){
                ans+=disx/2*2;
            }else{//情况2
                ans+=(disx+1)/2*2;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}
最后修改:2023 年 12 月 31 日
如果觉得我的文章对你有用,请随意赞赏