当前位置: 代码迷 >> 综合 >> UVa439---Knight Moves(BFS应用)
  详细解决方案

UVa439---Knight Moves(BFS应用)

热度:70   发布时间:2023-12-26 16:44:48.0

题目描述

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find theshortest closed tour of knight moves that visits each square of a given set of n squares on a chessboardexactly once. He thinks that the most difficult part of the problem is determining the smallest numberof knight moves between two given squares and that, once you have accomplished this, finding the tourwould be easy.Of course you know that it is vice versa. So you offer him to write a program that solves the”difficult” part.Your job is to write a program that takes two squares a and b as input and then determines thenumber of knight moves on a shortest route from a to b.

Input

The input file will contain one or more test cases. Each test case consists of one line containing twosquares separated by one space. A square is a string consisting of a letter (a..h) representing the columnand a digit (1..8) representing the row on the chessboard.

Output

For each test case, print one line saying ‘To get from xx to yy takes n knight moves.’

Sample Input

e2 e4

a1 b2

b2 c3

a1 h8

a1 h7

h8 a1

b1 c3

f6 f6

Sample Output

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.

题意:给你一个起点与终点,按照马在棋盘里走的规则,问从起点到终点最少走几步([bfs] 宽度优先搜索的应用);

代码如下

 

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int rstep[9][9];//标记坐标是否已经走过 
int dir[8][2] = {
   {-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//八个方向对应的坐标变换(马的位置为(4,4)),依次对应上图中1,2,3,4,5,6,7,8; 
struct node{int x;//记录坐标x int y;//记录坐标y int step;//记录最短步数 
};
node start,endd;//起点与终点的定义 (注意不可用end定义终点,c++中end有意义,会导致编译错误 )
int bfs()
{memset(rstep,0,sizeof(rstep));//每次宽度优先搜索前,重新清零步数 node pre,cur;start.step = 0;queue<node> q;q.push(start);rstep[start.x][start.y] = 1;// 开始对第一个坐标进行标记 while(!q.empty()){pre = q.front();q.pop();if(pre.x == endd.x&&pre.y == endd.y)return pre.step;for(int i = 0; i < 8; i++){cur.x = pre.x + dir[i][0];cur.y = pre.y + dir[i][1];if(cur.x<1||cur.x>8||cur.y<1||cur.y>8)continue;//坐标不满足条件 if(rstep[cur.x][cur.y]==1)continue;// 坐标不满足的条件 rstep[cur.x][cur.y] = 1;// 标记已走坐标 cur.step = pre.step + 1;// 增加相应的步数,避免重复 q.push(cur);}}return -1;
}
int main()
{char s1,s2,s3,s4;int n1,n2;while(scanf("%c%d %c%d",&s1,&n1,&s3,&n2)!=EOF){getchar();start.x=s1-'a'+1;start.y=n1;endd.x=s3-'a'+1;endd.y=n2;	int Min;if(start.x==endd.x&&start.y==endd.y)Min=0;elseMin=bfs();printf("To get from %c%d to %c%d takes %d knight moves.\n",s1,n1,s3,n2,Min);}}


对应BFS的总结:简单一句话就是和游戏中的“影分身”差不多吧O(∩_∩)O哈哈~。

 

每一次可以走到的点放到队列里。然后抛出队首的元素,进行判断,把每个可以走到点继续压入队列里(影分身(*^__^*) ),并进行步数统计,直到队列为空或找到终点元素

为止。