zroi 最短距离

· · 个人记录

关于题,由于权限之类的各种原因,这里就不放题目或者图片了,只放一个 网址

画图手推,可以发现

在没有限制条件的情况下沿着对角线走,当到达了终点所在行或列时,再拐过去直着走,这样就能够得到一条最短路。

而这题中的限制只能限制其中一个方向,剩下7个方向还是随便走的,只不过有些用不上

当终点在某一象限内:

当朝向终点方向的对角线走法被ban了之后,距离就确定为s+t了,很容易证明:若走了与终点相反的点,那么一定不是最短路。

当其中一个横竖走的方向被禁了呢。我们可以在到达那一行/列时判断下,要走的方向能走就直接走,那么这个限制条件并不会改变我们的最短路。

当被禁掉的方向正好是我们沿着对角线走后要去的那个方向时,我们可以沿这个方向两边的对角线,来一波蛇皮走位,如果差的步数为偶数,那么正好可以到达;为奇数的话,到达的肯定是与终点相邻的一格,+1即可。

对于其他本来就不去走的方向,限制了也没有用。

注意:对于不同的象限要稍加处理

当终点在坐标轴上:

终点方向能直接走就直走,不能的话同上,判断下步数的奇偶性。

当终点在原点:

那还走啥?

#include<bits/stdc++.h>
using namespace std;

int bx,by,s,t,path,ans;

int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>bx>>by>>s>>t;
    path = max(abs(s),abs(t));
/****************************************/
    if(s > 0 && t > 0){
        if(bx == 1 && by == 1){
            ans = s + t;
        }
        else if(bx == 1 && !by){
            if(s>t){
                if((s-t)%2)
                    ans = s+1;
                else ans = s;
            }
            else{
                ans = t;
            }
        }
        else if(by == 1 && !bx){
            if(s<t){
                if((t-s)%2)
                    ans = t+1;
                else ans = t;
            }
            else{
                ans = s;
            }
        }
        else{
            ans = path; 
        }
    }
/*************************************/
    else if(s > 0 && t < 0){
        t = abs(t);
        if(bx == 1 && by == -1){
            ans = s + t;
        }
        else if(bx == 1 && !by){
            if(s>t){
                if((s-t)%2)
                    ans = s+1;
                else ans = s;
            }
            else{
                ans = t;
            }
        }
        else if(by == -1 && !bx){
            if(s<t){
                if((t-s)%2)
                    ans = t+1;
                else ans = t;
            }
            else{
                ans = s;
            }
        }
        else{
            ans = path; 
        }
    }
/********************************************/
    else if(s < 0 && t > 0){
        s = abs(s);
        if(bx == -1 && by == 1){
            ans = s + t;
        }
        else if(bx == -1 && !by){
            if(s>t){
                if((s-t)%2)
                    ans = s+1;
                else ans = s;
            }
            else{
                ans = t;
            }
        }
        else if(by == 1 && !bx){
            if(s<t){
                if((t-s)%2)
                    ans = t+1;
                else ans = t;
            }
            else{
                ans = s;
            }
        }
        else{
            ans = path; 
        }
    }
/*************************************/
    else if(s < 0 && t < 0){
        s = abs(s);
        t = abs(t);
        if(bx == -1 && by == -1){
            ans = s + t;
        }
        else if(bx == -1 && !by){
            if(s>t){
                if((s-t)%2)
                    ans = s+1;
                else ans = s;
            }
            else{
                ans = t;
            }
        }
        else if(by == -1 && !bx){
            if(s<t){
                if((t-s)%2)
                    ans = t+1;
                else ans = t;
            }
            else{
                ans = s;
            }
        }
        else{
            ans = path; 
        }
    }
    else if(s > 0 && !t){
        if(bx == 1 && by == 0 && s%2){
            ans = s+1;
        }
        else{
            ans = s;
        }
    }
    else if(s < 0 && !t){
        s = abs(s);
        if(bx == -1 && by == 0 && s%2){
            ans = s+1;
        }
        else{
            ans = s;
        }
    }
    else if(!s && t > 0){
        if(bx == 0 && by == 1 && t%2){
            ans = t+1;
        }
        else{
            ans = t;
        }
    }
    else if(!s && t < 0){
        t = abs(t);
        if(bx == 0 && by == -1 && t%2){
            ans = t+1;
        }
        else{
            ans = t;
        }
    }
    else{
        ans = 0;
    }
    cout<<ans;
}

要注意的是:即使是类似的步骤也不要直接复制,就比如这题考试时候直接复制,两种不同的情况用一样的方法判断了(要是真的是相同的重复做还是定义个函数,改着用着都方便)

这题数据范围改改,多加一些限制条件好像能成 A* 的题