首页 > 代码库 > 马的移动

马的移动

题目描述

zzq很喜欢下国际象棋,一天,他拿着国际象棋中的“马”时突然想到一个问题:
给定两个棋盘上的方格a和b,马从a跳到b最少需要多少步?
现请你编程解决这个问题。

提示:国际象棋棋盘为8格*8格,马的走子规则为,每步棋先横走或直走一格,然后再往外斜走一格。

输入

输入包含多组测试数据。每组输入由两个方格组成,每个方格包含一个小写字母(a~h),表示棋盘的列号,和一个整数(1~8),表示棋盘的行号。

输出

对于每组输入,输出一行“To get from xx to yy takes n knight moves.”。

样例输入

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

样例输出

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.
题意描述:

输入起点坐标和终点坐标

计算并输出按照马的特殊走法从起点走到终点的最少步数。

解题思路:

用广度优先搜索计算图中两点间的最短路径。

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 struct note
 4 {
 5     int x,y,s;
 6 };
 7 int main()
 8 {
 9     char list[9];
10     int sx,sy,fx,fy,flag,k,tx,ty;
11     struct note q[100];
12     int head,tail,a[11][11];
13     int next[8][2]={
14         {1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
15     while(gets(list) != NULL)
16     {
17         sx=list[0]-a+1;
18         sy=list[1]-0;
19         fx=list[3]-a+1;
20         fy=list[4]-0;
21         if(sx==fx&&sy==fy)
22         {
23             printf("To get from %c%c to %c%c takes 0 knight moves.\n",list[0],list[1]
24             ,list[3],list[4]);
25             continue;
26         }
27         head=1;tail=1;
28         q[tail].x=sx;
29         q[tail].y=sy;
30         q[tail].s=0;
31         memset(a,0,sizeof(a));
32         a[sx][sy]=1;
33         tail++;
34         
35         flag=0;
36         while(head<tail)
37         {
38             
39             for(k=0;k<=7;k++)
40             {
41                 tx=q[head].x+next[k][0];
42                 ty=q[head].y+next[k][1];
43                 if(tx<1 || tx>8 || ty<1 || ty>8)
44                     continue;
45                 if(a[tx][ty]==0)
46                 {
47                     a[tx][ty]=1;
48                     q[tail].x=tx;
49                     q[tail].y=ty;
50                     q[tail].s=q[head].s+1;
51                     tail++;
52                 }
53                 if(tx==fx&&ty==fy)
54                 {
55                     flag=1;
56                     break;
57                 }
58             }
59             if(flag==1)
60                 break;
61             head++;
62         }
63         printf("To get from %c%c to %c%c takes %d knight moves.\n",list[0],list[1]
64             ,list[3],list[4],q[tail-1].s);
65     }
66         return 0;
67 }

易错分析:

1、此题虽然题意未说不能重复走,但是还是不能重复走的,所以记得标记已经走过的路

2、初始化标标记数组

3、注意当起点坐标和终点坐标相等的时候输出0

4、棋盘的边界判断,关键是8*8方格要理解清楚

样例测试:

h1 a4

f1 e6

a1 a2

样例输出:

To get from h1 to a4 takes 4 knight moves.

To get from f1 to e6 takes 4 knight moves.

To get from a1 to a2 takes 3 knight moves.

马的移动