本题关键在于分析棋盘上王、后、车、象的行走规则。
设起点坐标为(x1,y1),终点坐标为(x2,y2);dx=abs(x1,x2),dy=abs(y1-y2)。

1. 王可以横、竖、斜走,每步一格
所需最小步数为min(dx,dy)+abs(dx-dy)
对于橘黄色三角所在的特殊位置,先竖着走再斜着走和两次都斜着走所用的步数是一样的
2. 后可以横、竖、斜走,每步格数不限
横、竖、斜1步走到,否则2步走到
3. 车可以横、竖走,每步格数不限
横、竖1步走到,否则2步走到
4. 象只能斜走,每步格数不限
如果所在位置的横纵坐标之差为奇数,会落入图中黑色方格内,如果之差为偶数,会落入图中白色方格内。象每斜着走一步,它的横纵坐标增加或减少的绝对值相等,所以它的横纵坐标之差的奇偶性不会变。
因此图中的任一点斜着走会分成黑白两道,白色方格斜着走必定会落入白色方格,黑色方格斜着走必定还落入黑色方格,两者互相不可达。因此如果起点和终点不是同一类方格,则不可达。如果起点和终点属于同一类方格,要么斜着1步可达,否则2步可达,因为如图所示,任何一个位于蓝线上的白色方格通过一步斜走可以到达任何一个其他白色方格所在的蓝线,然后再斜走一步即可到达该蓝线上的目标方格(或者先在自己所在的蓝线上一步斜走到对应位置,再一步斜走到达目标方格)
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int t;
cin>>t;
char s1[3],s2[3];
while(t--)
{
cin>>s1>>s2;
int x1,x2,y1,y2;
int a,b,c,d;
x1=s1[0]-'a'+1;
y1=s1[1]-'1'+1;
x2=s2[0]-'a'+1;
y2=s2[1]-'1'+1;
if(x1==x2 && y1==y2)
{
cout<<0<<' '<<0<<' '<<0<<' '<<0<<endl;
}
else{
int dx=abs(x1-x2);
int dy=abs(y1-y2);
int cx=abs(x1-y1);
int cy=abs(x2-y2);
a = abs(dx-dy) + min(dx,dy);
if(dx==dy || dx==0 || dy==0)
b=1;
else b=2;
if(dx==0 || dy==0)
c=1;
else c=2;
if(dx==dy)
d=1;
else if(cx%2 == cy%2)
d=2;
else d=-1;
cout<<a<<' '<<b<<' '<<c<<' ';
if(d!=-1)
cout<<d<<endl;
else cout<<"Inf"<<endl;
}
}
return 0;
}
博客分析了棋盘上王、后、车、象四种棋子从起点到终点的最短步数计算方法。王的最短步数为横、竖、斜的最小步数之和;后和车的最短步数取决于是否一步可到达;象的行走受到横纵坐标奇偶性影响,不同颜色格子之间可能无法到达。

379

被折叠的 条评论
为什么被折叠?



