//getchar();忘了,纠结我好几个小时!!!!千万不能忘了!
在国际象棋中Knight称“马”或“骑士”,Knight的走法和中国象棋中马相同,同样是走“日”字,
或英文字母大写的“L”形:即先向左(或右)走1格,再向上(或下)走2格;或先向左(或右)
走2格,再向上(或下)走1格。不同的是,囯际象棋的Knight没有“绊马脚”的限制,故Knight可越过其
他棋子。吃子与走法相同。
如图:
#include<stdio.h> #include<string.h> #include<queue> #include<conio.h> using namespace std; int vst[17][17]; // 访问标记 int dir[8][2]={1,-2,1,2,2,1,2,-1,-1,2,-1,-2,-2,1,-2,-1}; // 方向向量 int row1,row2; char col1,col2; struct State // BFS 队列中的状态数据结构 { int x,y; // 坐标位置 int counter; // 搜索步数统计器 }; int CheckState(State s) // 约束条件检验 { if(!vst[s.x][s.y]&&s.x<8&&s.x>=0&&s.y<8&&s.y>=0) // 满足条件 return 1; else // 约束条件冲突 return 0; } int bfs(State st) { int i; memset(vst,0,sizeof(vst)); queue <State> q; // BFS 队列 State now,next; // 定义2 个状态,当前和下一个 st.counter=0; // 计数器清零 q.push(st); // 入队 vst[st.x][st.y]=1; // 访问标记 while(!q.empty()) { now=q.front(); // 取队首元素进行扩展 if(now.x==(int)(col2-'a')&&now.y==row2-1) // 出现目标态,此时为Step_Counter 的最小值,可以退出即可 { return now.counter; } for(i=0;i<8;i++) { next.x=now.x+dir[i][0]; // 按照规则生成 下一个状态 next.y=now.y+dir[i][1]; next.counter=now.counter+1; if(CheckState(next)) // 如果状态满足约束条件则入队 { q.push(next); vst[next.x][next.y]=1; //访问标记 } } q.pop(); // 队首元素出队 } return 0; } int main() { //freopen("in.txt","r",stdin); State start; while(scanf("%c%d %c%d",&col1,&row1,&col2,&row2)!=EOF) { //col1=(col1-'a'+1); //col2=(col2-'a'+1); // memset(vst,0,sizeof(vst)); //(int)col1;(int)col2; start.x=col1-'a'; start.y=row1-1; printf("To get from %c%d to %c%d takes %d knight moves.\n",col1,row1,col2,row2,bfs(start)); getchar(); } return 0; }