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* 的题