寒假訓練二里面的A題,搜了一下發現題庫居然還有一題名字一樣的。
正好方法也差不多,所以順便就一起寫了。(廣搜優先)
TOJ 1133: Knight Moves
描述
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.
輸入
The input 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.
輸出
For each test case, print one line saying "To get from xx to yy takes n knight moves.".
樣例輸入
樣例輸出
題目意思:有一顆棋子A走到B需要幾步。以下用的是廣搜,還有用棧的地方我詳細解說了。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int c[9][9];int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//8種走法 typedef struct{ int x,y,count;}node;node start,finish;int bfs(){ memset(c,0,sizeof(c));//作用等同于int c[9][9]={0}; node pre,cur; start.count=0; queue<node> q;//創建隊列q q.push(start);//push(x) 將x壓入隊列的末端 c[start.x][start.y]=1;//起點走過了 while(!q.empty())//隊列非空 { pre=q.front();//返回第一個元素(隊頂元素) q.pop();//彈出隊列的第一個元素(隊頂元素) if(pre.x==finish.x&&pre.y==finish.y)//走到終點了 return pre.count; 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(c[cur.x][cur.y]==1)continue;//==1就是走過了 ,防止走回頭路 c[cur.x][cur.y]=1;//標記走過了 cur.count=pre.count+1;//步數+1 q.push(cur); } } return -1;}int main(){ char row,end; int col,ed; int min; while(scanf("%c%d %c%d",&row,&col,&end,&ed)!=EOF) { getchar(); start.x = row-'a'+1; start.y = col; finish.x = end-'a'+1; finish.y = ed; if(start.x==finish.x&&start.y==finish.y) min=0; else min=bfs(); printf("To get from %c%d to %c%d takes %d knight moves./n",row,col,end,ed,min); } return 0;}下面這題差不多,都是數字還簡單點了...用的也是廣搜優先。
然后在我百度的時候搜到一篇講這個的,感覺很不錯,因為他化簡了。
還沒拿到轉載權..就貼個地址吧...
http://blog.csdn.net/nameofcsdn/article/details/52025142
TOJ 2481: Knight Moves
描述
BackgroundMr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him?The Problem Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance to be faster than Somurolov.For people not familiar with chess, the possible knight moves are shown in Figure 1.
輸入
The input begins with the number n of scenarios on a single line by itself.Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board (4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers {0, ..., l-1}*{0, ..., l-1} specifying the starting and ending position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess board of that scenario.
輸出
For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point. If starting point and ending point are equal,distance is zero. The distance must be written on a single line.
樣例輸入
樣例輸出
題目意思:(數據代入說明)有3組數據,第一組數據,棋盤大小8*8,從(0,0)走到(7,0)需要5步。
這個是直接改的上面的代碼。就是在判斷出界的時候把>改成>=。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int c[301][301];//棋盤最大300 int m,dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//8種走法 typedef struct{ int x,y,count;}node;node start,finish;int bfs(){ memset(c,0,sizeof(c));//作用等同于int c[301][301]={0}; node pre,cur; start.count=0; queue<node> q;//創建隊列q q.push(start);//push(x) 將x壓入隊列的末端 c[start.x][start.y]=1;//起點走過了 while(!q.empty())//隊列非空 { pre=q.front();//返回第一個元素(隊頂元素) q.pop();//彈出隊列的第一個元素(隊頂元素) if(pre.x==finish.x&&pre.y==finish.y)//走到終點了 return pre.count; for(int i=0;i<8;i++) { cur.x=pre.x+dir[i][0]; cur.y=pre.y+dir[i][1]; if(cur.x<0||cur.x>=m||cur.y<0||cur.y>=m)continue;//出界了 這里改了>=m if(c[cur.x][cur.y]==1)continue;//==1就是走過了 ,防止走回頭路 c[cur.x][cur.y]=1;//標記走過了 cur.count=pre.count+1;//步數+1 q.push(cur); } } return -1;}int main(){ int min,n; scanf("%d",&n); while(n--) { scanf("%d %d %d %d %d",&m,&start.x,&start.y,&finish.x,&finish.y); if(start.x==finish.x&&start.y==finish.y) min=0; else min=bfs(); printf("%d/n",min); } return 0;}然后我在網上找了個簡潔版...
#include<cstdio>#include<cstring>#include<queue>using namespace std;const int dir[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};struct node{int x,y,step;};bool used[301][301];int n;int startx,starty,endx,endy;node cur,pre;int bfs(){ int i,x,y; queue<node>que; cur.x=startx,cur.y=starty,cur.step=0; memset(used,0,sizeof(used)); used[startx][starty]=1; que.push(cur); while(!que.empty()) { cur=que.front(),que.pop(); if(cur.x==endx&&cur.y==endy) return cur.step; for(i=0;i<8;i++) { x=cur.x+dir[i][0]; y=cur.y+dir[i][1]; if(x>=0&&x<n&&y>=0&&y<n&&!used[x][y]) { used[x][y]=1; pre.x=x,pre.y=y,pre.step=cur.step+1; que.push(pre); } } } return -1;}int main(){ int tCase; scanf("%d",&tCase); while(tCase--) { scanf("%d",&n); scanf("%d%d%d%d",&startx,&starty,&endx,&endy); printf("%d/n",bfs()); } return 0;}
新聞熱點
疑難解答