给一个8*8的棋盘,给出骑士的起点和终点,求出从起点到终点的走的最小步数。这个也是ZOJ 的1091题。
用bfs解决,一个vis数组保存是否访问过,dis数组保存从起点到该点的移动次数。代码如下:

1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 using namespace std; 5 6 queue<int> q; 7 int d[][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1,-2}, {2, -1}}; 8 int vis[8][8], dis[8][8]; 9 int end_x, end_y; 10 11 int bfs(int x, int y) 12 { 13 vis[x][y] = 1; 14 dis[x][y] = 0; 15 while(!q.empty()) q.pop(); 16 int t; 17 t = x * 8 + y; 18 q.push(t); 19 while(!q.empty()) 20 { 21 t = q.front(); 22 q.pop(); 23 x = t / 8; 24 y = t % 8; 25 if(x == end_x && y == end_y) return dis[x][y]; 26 for(int i = 0; i < 8; i++) 27 { 28 int nx = x+d[i][0], ny = y+d[i][1]; 29 if(nx >= 0 && nx < 8 && ny >= 0 && ny < 8 && !vis[nx][ny]) 30 { 31 vis[nx][ny] = 1; 32 dis[nx][ny] = dis[x][y] + 1; 33 t = nx * 8 + ny; 34 q.push(t); 35 } 36 } 37 } 38 return -1; 39 } 40 41 int main() 42 { 43 #ifdef LOCAL 44 freopen("in", "r", stdin); 45 #endif 46 char start[5], end[5]; 47 while(scanf("%s%s", start, end) != EOF) 48 { 49 int x, y; 50 x = start[1] - '1'; 51 y = start[0] - 'a'; 52 end_x = end[1] - '1'; 53 end_y = end[0] - 'a'; 54 memset(vis, 0, sizeof(vis)); 55 memset(dis, 0, sizeof(dis)); 56 int ans = bfs(x, y); 57 printf("To get from %s to %s takes %d knight moves.\n", start, end, ans); 58 } 59 return 0; 60 } 61