Knight Moves
Problem Description
A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would 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 the number 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 two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and 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.
题意:就是之前写过的马走日问题,8*8的棋盘,可以直走或垂直走,紧接着还要向外走一步。输入起始点和终止点,输出从起到终的步数。
思路:从起始点开始一层一层往外搜,队头初始化为起始点,找到队列的当前队头,找到后用一个结构体存好并将当前队头出队,搜索该队头的8个方向,期间若有满足条件的坐标,加入队列,进行下一次搜索,直到找到终止点或队列为空,函数结束,输出步数。
自己这次是学习了c++的queue类之后来重写的这道题,之前是用c模拟队列,不得不说c++的queue用着省心了很多
#include#include #include #include using namespace std;char s1[3],s2[3];//读入起始坐标和终止坐标 int book[10][10];//标记已经走过的位置 int NEXT[8][2] = {1,2,-1,-2,1,-2,-1,2,2,1,-2,-1,2,-1,-2,1};//方向 int start_i,start_j;//起始点 int end_i,end_j;//终止点 int step;//步数 int i,j;struct note{ int x; int step; int y;};void BFS(note front_head)//BFS { queue Q;//建立空队列 Q.push(front_head);//将起始点加入队列 note next_queue;//下一个队列元素 note now_head;//当前队头元素 while(!Q.empty())//循环条件是队列不为空 { now_head = Q.front();//找到当前队头元素 Q.pop();//已经找到则出队 for(i = 0; i < 8; i ++)//搜索8个方向 { next_queue.x = now_head.x + NEXT[i][0]; next_queue.y = now_head.y + NEXT[i][1]; if(next_queue.x < 0||next_queue.y <0||next_queue.x > 7||next_queue.y > 7) continue; if(book[next_queue.x ][next_queue.y ]!= 1)//没有走过该点 { book[next_queue.x ][next_queue.y ] = 1; next_queue.step = now_queue.step+1; Q.push(next_queue);//将找到满足条件的下一个队列元素加入队尾 //如果下一个队列元素满足终止条件,结束函数 if(next_queue.x == end_i&&next_queue.y == end_j) { step = next_queue.step; return; } } } } return;}int main(){ while(scanf("%s%s",s1,s2)!=EOF) { memset(book,0,sizeof(book)); note front; step = 0;//步数初始化,不要忘 //提取起始点,终止点 start_i = s1[0]-'a'; start_j = s1[1]-'1'; end_i = s2[0]-'a'; end_j = s2[1]-'1'; //初始化起始点 front.step = 0; front.x = start_i; front.y = start_j; //标记起始点为已经走过 book[front.x][front.y]= 1; //开始搜索 BFS(front); printf("To get from %s to %s takes %d knight moves.\n",s1,s2,step); } return 0;}