题目大意
国际象棋的棋盘是黑白相间的8 * 8的方格,棋子放在格子中间。如下图所示:
王、后、车、象的走子规则如下:
王:横、直、斜都可以走,但每步限走一格。
后:横、直、斜都可以走,每步格数不受限制。
车:横、竖均可以走,不能斜走,格数不限。
象:只能斜走,格数不限。
写一个程序,给定起始位置和目标位置,计算王、后、车、象从起始位置走到目标位置所需的最少步数。
思路分析
一开始想的bfs,实在不行双向bfs,静下心来思考一下其实没有这么麻烦,根本不需要搜索。
令x = abs(s1[0] - s2[0]), y = abs(s1[1] - s2[1]);
- 王:根据他的行走策略,他肯定可以到达任何地方,并且步数为:
max(x, y);
,为什么?比如我们要从黑圈走到黄圈,x=3,y=2,我们需要x-y
步就可以走到y*y
的正方形边缘有没有?然后斜着走y步就可以了,因此总共需要 x − y + y = x x-y+y=x x−y+y=x步。
- 后比较好判断,始末位置处于对角线或者共线就是1,否则就是2.
- 车只有始末位置共线才是1,否则是2.
- 象比较麻烦,不过我们可以发现,初始状态在黑盘上的象只能到达黑盘,而且只需要两步,白盘同理。因此我们只需要判断始末状态是不是一个颜色,即
(x+y)%2==0
//memory:200K time:0ms
#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
#define ll int
#define MAX 50
int main() {
ll t, a, b, c, d; scanf("%d", &t);
string s1, s2;
for (int i = 1; i <= t; i++) {
a = b = c = d = 0;
cin >> s1 >> s2;
if (s1 == s2) { printf("%d %d %d %d\n", a, b, c, d); continue; }
ll x = abs(s1[0] - s2[0]), y = abs(s1[1] - s2[1]);
a = max(x, y);
if (s1[0] == s2[0] || s1[1] == s2[1])b = c = 1;//直线
else if (x == y)b = d = 1, c = 2;//对角线
else b = c = 2;
if (!d && (abs(s1[0] - s2[0]) + abs(s1[1] - s2[1])) % 2 == 0) d = 2;//不是对角线
else if (!d)d = -1;
if (d != -1)printf("%d %d %d %d\n", a, b, c, d);
else printf("%d %d %d Inf\n", a, b, c);
}
}