HNCU1101:马的移动---BFS
題目描述
小明很喜歡下國際象棋,一天,他拿著國際象棋中的“馬”時突然想到一個問題:
給定兩個棋盤上的方格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.
很明顯的,最短路徑,用廣度搜索算法。網上找的代碼注釋下
#include <stdio.h> #include <queue> #include <string.h> using namespace std;struct node {int x,y,step; }; //結點 int vis[8][8]; //存放訪問點 int sx,sy,ex,ey,ans; //起點 末點 int to[8][2]={-1,-2,-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2}; //馬可能的坐標移動 8種可能 int check(int x,int y) {if(x<0 || y<0 || x>=8 || y>=8)return 1;if(vis[x][y])return 1;return 0; } // 檢測是否到末尾 結點是否被訪問。 void bfs() {int i;queue<node> Q; //廣度搜索的隊列 先進先出。node a,next;a.x = sx; a.y = sy;a.step = 0;vis[sx][sy] = 1;Q.push(a);while(!Q.empty()){a = Q.front();Q.pop();if(a.x == ex && a.y == ey){ans = a.step;return ;} //如果起點 末點相同 step=0for(i = 0;i<8;i++){next = a;next.x+=to[i][0];next.y+=to[i][1]; //訪問相鄰八個結點if(check(next.x,next.y))continue; //出現墻 被訪問 繼續next.step = a.step+1; 找出8步后 步數加1vis[next.x][next.y] = 1; //標記訪問過的點。Q.push(next);} }return ; }int main() {char ch1[10],ch2[10];while(~scanf("%s%s",ch1,ch2)){sx = ch1[0]-'a';sy = ch1[1]-'1';ex = ch2[0]-'a';ey = ch2[1]-'1';memset(vis,0,sizeof(vis));bfs();printf("To get from %s to %s takes %d knight moves.\n",ch1,ch2,ans);}return 0; }
總結
以上是生活随笔為你收集整理的HNCU1101:马的移动---BFS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU1978 记忆化搜索
- 下一篇: 图的遍历递归和非递归实现