1、问题描述:
Description
王、后、车、象的走子规则如下:
- 王:横、直、斜都可以走,但每步限走一格。
- 后:横、直、斜都可以走,每步格数不受限制。
- 车:横、竖均可以走,不能斜走,格数不限。
- 象:只能斜走,格数不限。
写一个程序,给定起始位置和目标位置,计算王、后、车、象从起始位置走到目标位置所需的最少步数。
Input
Output
Sample Input
2
a1 c3
f5 f8
Sample Output
2 1 2 1
3 1 1 Inf
二、解题思路自我理解:
①、本题的关键在于一个是理解清楚各中棋子的移动规则,第二个是恰当的表示起始位置和重点位置的表示,设起点和终点位置在水平方向上的距离是X,起点和终点在竖直方向上的距离是y。根据题目输入输出要求,用字符串数组储存起点和终点位置,char begin[5]、 char end[5]分别储存的是起点和终点的位置,显然起点和终点在水平方向的距离x=abs(begin[0]-end[0]), 起点和终点在竖直方向的距离是y=abs(begin[1]-end[1]);
②、对于王来说,横竖斜都可以走,但只能走一步,所以王的最少步子走法应该是先走一个等腰三角形的斜边(等腰边长是xy中两者小者),然后直线走abs(x-y),对于在起点和终点的同一水平线或同一竖直线,可以理解为等腰三角形的等腰边为0即可; (min(x,y) + abs(x-y) = max(x,y) )
③、对于后来说,由于每步格子不限,如果起点和终点在同一条水平线(y=0)或者在同一竖直线上(x=0)或在等腰三角形斜边上(x=y),那么一步到位,如果不是,那么就是先一步走等腰三角形斜边,第二步走xy差值;
④、对于车来说,不能斜走但横竖步数不限,那么要么是一步(起点终点处于同一水平线或竖直线),要么两步(先横后竖或者先竖后横);
⑤、对于象来说,只能斜走,那么存在不可达情况。斜走的一个重要特性是走的前后两点其在棋盘上的横纵坐标差的奇偶性不会改变,意思是说只要两点横纵坐标差同为奇数或同为偶数,就可达,否则不可达(Inf);对于可达情况的步数的确定,如果起点和终点在一个等腰三角形的上(横坐标差x = 纵坐标差y),那么就是一步。否则就是两步。
⑥、由于在第⑤点中涉及到到了每个坐标的横纵差(abs(begain[0]-begain[1])、abs(end[0]-end[1])),前面只定义了起点终点坐标的的相对横纵差(x=abs(begin[0]-end[0])、y=abs(begin[1]-end[1])),一种比较低效的编码方法是: 不可达情况即if( (abs(begin[0]-begin[1])%2==0&&abs(end[0]-end[1])%2!=0) ||(abs(begin[0]-begin[1])%2!=0&&abs(end[0]-end[1])%2==0) ) printf("Inf\n"); 一种比较好的编码方法是 if(abs(x-y)%2 !=0) printf("Inf\n"); ---- 两点横纵坐标差同为奇数或同为偶数,根据同奇偶相减为偶的原则即 abs【abs(begain[0]-begain[1]) - abs(end[0]-end[1])】为偶数即可,【不理解前面的abs(x-y)就为何等价于后面的abs嵌套,直接用后面的abs嵌套,直观】。
三、源码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int nCasses, i; //nCasses表示测试数据个数
scanf("%d", &nCasses);
for(i=0; i<nCasses; i++)
{
char begin[5], end[5];
scanf("%s %s", begin, end);
int x, y;
x = abs(begin[0] - end[0]);
y = abs(begin[1] - end[1]);
if( x==0 && y==0) printf("0 0 0 0\n");
else
{
if(x<y) printf("%d", y);
else printf("%d", x); //王的步子情况,棋盘中等腰三角形斜边和直边的格子数是一样的,min(x,y) + abs(x-y) = max(x,y)
if(x==y || x==0 || y==0) printf(" 1");
else printf(" 2");//后的步子情况
if(x==0 || y==0) printf(" 1");
else printf(" 2");//车的步子情况
if(abs(x-y)%2 !=0) printf("Inf\n");
else if(x==y) printf(" 1\n");
else printf(" 2\n");//象的步子情况
}
}
system("pasue");
return 0;
}