这道题目有个坑踩到了,就是我没玩过国际象棋,以为斜着走只能走斜率为正负1的直线走一次。。。
题目
ZCMU-1345
1345: 国际象棋
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 224 Solved: 75
[Submit][Status][Web Board]
Description
国际象棋的棋盘是黑白相间的8 * 8的方格,棋子放在格子中间。
王、后、车、象的走子规则如下:
王:横、直、斜都可以走,但每步限走一格。
后:横、直、斜都可以走,每步格数不受限制。
车:横、竖均可以走,不能斜走,格数不限。
象:只能斜走,格数不限。
你的任务是写一个程序,给定起始位置和目标位置,计算王、后、车、象从起始位置走到目标位置所需的最少步数。
Input
第一行是测试数据的组数t(0 <= t <= 20)。以下每行是一组测试数据,每组包括棋盘上的两个位置,第一个是起始位置,第二个是目标位置。位置用"字母-数字"的形式表示,字母从"a"到"h",数字从"1"到"8"。
Output
对于输入的每组测试数据,输出王、后、车、象所需的最少步数。如果无法到达,就输出"Inf".
Sample Input
2
a1 c3
f5 f8
Sample Output
2 1 2 1
3 1 1 Inf
HINT
请使用%s读入字符串
想法
这道题其实是简单模拟,但是还是有几个点要注意一下的
首先我们把起点和终点的相对位置做一个分类。分为三类:
1.起点和终点同行或者同列
2.起点和终点在绝对值斜率为1的直线上
3.其他情况
这里面特别注意斜着走的有三种情况,一种是不能走,一种是一步走到,还有是走两步
首先,如果斜着能走到的话,那么起点和终点必须同色(上方棋盘中),也就是说起点横纵坐标相加和终点横纵坐标相加要同奇偶,这样再判断是否在绝对值斜率为1的直线上,如果是就是1步走到,不是则为两步走到
其他情况就简单了,我们直接上代码!
AC代码
#include<bits/stdc++.h>
using namespace std;
#define gcd __gcd;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x);
int dis_a,dis_b,dis_c,dis_d;
int main(){
int T;
int flag1,flag2;
int Xs,Ys,Xe,Ye;
char input1[5],input2[5];
scanf("%d",&T);
while(T--)
{
//flag1标记起始和终点是否在同一行或者同一列
//flag2标记是否在斜率为1的直线上
flag1 = flag2 = 0;
scanf("%s%s",input1,input2);
Xs = input1[0] - 'a' + 1;Ys = input1[1] - '0';
Xe = input2[0] - 'a' + 1;Ye = input2[1] - '0';
// cout << Xs << " " << Ys << endl;
// cout << Xe << " " << Ye << endl;
if(Xs==Xe&&Ys==Ye){
printf("0 0 0 0\n");
continue;
}
if(Xs==Xe||Ys==Ye)flag1 = 1;
if(fabs(Ys-Ye)==fabs(Xs-Xe))flag2 = 1;
if(flag1){
dis_a = fabs(Xs-Xe) + fabs(Ys-Ye);
dis_b = 1;
dis_c = 1;
if((Xs+Ys)+(Xe+Ye)&1)//检查起点和终点是否在同色棋盘上
printf("%d %d %d %s\n",dis_a,dis_b,dis_c,"Inf");
else
printf("%d %d %d %d\n",dis_a,dis_b,dis_c,2);
continue;
}
if(flag2){
dis_a = fabs(Xs-Xe);
dis_b = dis_d = 1;
dis_c = 2;
printf("%d %d %d %d\n",dis_a,dis_b,dis_c,dis_d);
continue;
}
dis_a = max(fabs(Xs-Xe),fabs(Ys-Ye));
dis_b = 2;
dis_c = 2;
if((Xs+Ys)+(Xe+Ye)&1)
printf("%d %d %d %s\n",dis_a,dis_b,dis_c,"Inf");
else
printf("%d %d %d %d\n",dis_a,dis_b,dis_c,2);
}
return 0;
}