UVa 439 - Knight Moves

  给一个8*8的棋盘,给出骑士的起点和终点,求出从起点到终点的走的最小步数。这个也是ZOJ 的1091题。

  用bfs解决,一个vis数组保存是否访问过,dis数组保存从起点到该点的移动次数。代码如下:

View Code
 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         

 

posted @ 2013-04-25 17:00  xiaobaibuhei  阅读(165)  评论(0编辑  收藏  举报