1657 Distance on Chessboard[思维]:30行代码的简洁思路

题目大意

国际象棋的棋盘是黑白相间的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 xy+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);
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值