骑士的移动
题意:骑士在一个8*8的棋盘上移动,1-8代表行号,a-h代表列号,给出骑士的初始位置和目的位置,求骑士最少的移动步数;题目隐含一层意思(骑士移动规则是中国象棋的“马”的走法)
输入:一串字符串,包含起始位置和目的位置;
输出:骑士的最少移动步数;
解题思路:看到最少,立马想到BFS,按层搜索,步数加1,最后输出总步数;
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 //mat[][]是骑士移动的8个方向; 5 int mat[10][3]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}}; 6 int q[100],vis[10][10],ans[10][10]; 7 8 void bfs(int r,int c){//bfs按层搜索; 9 int tail=1,head=0; 10 q[head]=r*8+c; 11 vis[r][c]=1; 12 while(tail>head){ 13 int p=q[head++]; 14 r=p/8,c=p%8; 15 for(int i=0;i<8;i++){ 16 int x=r+mat[i][0],y=c+mat[i][1]; 17 if(x>=0&&x<8 && y>=0&&y<8 && !vis[x][y]){ 18 q[tail++]=x*8+y; 19 ans[x][y]=ans[r][c]+1;//子节点的步数=父节点的步数加1; 20 vis[x][y]=1; 21 } 22 } 23 } 24 } 25 26 int main(){ 27 int n,m; 28 char a,b; 29 while(scanf("%c%d %c%d",&a,&n,&b,&m)!=EOF){ 30 getchar(); 31 memset(vis,0,sizeof(vis)); 32 memset(ans,0,sizeof(ans)); 33 bfs(n-1,a-'a');//n-1使坐标原点为(0,0); 34 printf("To get from %c%d to %c%d takes %d knight moves.\n",a,n,b,m,ans[m-1][b-'a']); 35 } 36 return 0; 37 }