跳马(Knight Moves), ZOJ1091, POJ2243 x
跳马(Knight Moves), ZOJ1091, POJ2243
题目描述:
给定象棋棋盘上两个位置 a 和 b,编写程序,计算马从位置 a 跳到位置 b 所需步数的最小值。
输入描述:
输入文件包含多个测试数据。每个测试数据占一行,为棋盘中的两个位置,用空格隔开。棋盘位置为两个字符组成的串,第 1 个字符为字母 a~h,代表棋盘中的列;第 2 个字符为数字字符1~8,代表棋盘中的行。
输出描述:
对输入文件中的每个测试数据,输出一行"To get from xx to yy takes n knight moves.", xx 和yy 分别为输入数据中的两个位置, n 为求得的最少步数。
样例输入: |
样例输出: |
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.
|
这道题其实就是裸的bfs
不过需要注意的是:输入输出的形式!
代码如下:
1)注释版:
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 char s[5]; 7 bool v[9][9]; 8 int ex,ey,sx,sy,ans; 9 int dx[8]={2,1,-1,-2,-2,-1,1,2}; 10 int dy[8]={-1,-2,-2,-1,1,2,2,1}; 11 struct node 12 { 13 int x,y,step; 14 }cur,nxt; 15 16 queue<node>q; 17 18 void bfs() 19 { 20 if(ex==sx&&ey==sy) //特判起点等于终点 21 { 22 printf("To get from %c%d to %c%d takes %d knight moves.\n",char(ex+'a'-1),ey,char(sx+'a'-1),sy,0); 23 return; 24 } 25 while(!q.empty()) q.pop(); // 多组数据初始化 26 memset(v,0,sizeof(v)); // 同上 27 cur.x=ex,cur.y=ey; cur.step=0; //起点 28 v[ex][ey]=true; //不要漏了标记起点 29 q.push(cur); 30 while(!q.empty()) 31 { 32 cur=q.front(); 33 q.pop(); //不要漏了当前出队 34 //v[cur.x][cur.y]=false; 出队,清楚标记,是否需要? 答案当然是否定的 35 for(int i=0;i<8;i++) //八方位搜索 36 { 37 int xx=cur.x+dx[i],yy=cur.y+dy[i]; 38 if(xx>0&&xx<=8&&yy>0&&yy<=8&&!v[xx][yy]) 39 { 40 if(xx==sx&&yy==sy) //如果找到了,第一个找到的一定就是最近的 41 { 42 printf("To get from %c%d to %c%d takes %d knight moves.\n",char(ex+'a'-1),ey,char(sx+'a'-1),sy,cur.step+1); 43 return ;//必须用return,或者也可以用多次break 44 } 45 nxt.x=xx, nxt.y=yy; nxt.step=cur.step+1; 46 v[nxt.x][nxt.y]=true;//标记 47 q.push(nxt); //将扩展出的状态入队 48 } 49 } 50 } 51 } 52 int main() 53 { 54 while(scanf("%s",s)!=EOF) 55 { 56 ex=s[0]-'a'+1; ey=s[1]-'0'; 57 scanf("%s",s); 58 sx=s[0]-'a'+1; sy=s[1]-'0'; 59 bfs(); 60 } 61 }
2)非注释版:(另一种方法,表示方向的换为一个二维数组)
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 struct node 10 { 11 int x,y; 12 }; 13 int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1}; 14 int dis[10][10]; 15 int ex,ey; 16 bool OK(node &b) 17 { 18 if(b.x<1||b.x>8||b.y<1||b.y>8||dis[b.x][b.y]) 19 return false; 20 return true; 21 } 22 void BFS(int x,int y) 23 { 24 node a,b; 25 queue<node> Q; 26 a.x=x;a.y=y; 27 Q.push(a); 28 int i; 29 while(!Q.empty()) 30 { 31 a=Q.front();Q.pop(); 32 for(i=0;i<8;i++) 33 { 34 b.x=a.x+dir[i][0]; 35 b.y=a.y+dir[i][1]; 36 if(b.x==x&&b.y==y) continue; 37 if(OK(b)) 38 { 39 dis[b.x][b.y]=dis[a.x][a.y]+1; 40 Q.push(b); 41 } 42 if(b.x==ex&&b.y==ey) return; 43 } 44 } 45 46 } 47 int main() 48 { 49 char op1[5],op2[5]; 50 while(scanf("%s %s",op1,op2)!=EOF) 51 { 52 memset(dis,0,sizeof(dis)); 53 int x=op1[0]-'a'+1,y=op1[1]-'0'; 54 ex=op2[0]-'a'+1;ey=op2[1]-'0'; 55 // printf("%d %d==\n",ex,ey); 56 if(x!=ex||y!=ey) 57 BFS(x,y); 58 printf("To get from %s to %s takes %d knight moves.\n",op1,op2,dis[ex][ey]); 59 60 } 61 }