Knight Moves (UVa 439) BFS

题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=839&page=show_problem&problem=380

思路:用 BFS 求出到终点的最短距离即可。

小技巧:用一个 dir 数组和两个 for 循环将与一个节点连接的八个节点枚举出来。

/* Knight Moves (UVa 439) */
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

const int maxn = 10;

struct Point{
    int r, c, cnt;
    Point(int r, int c, int cnt): r(r), c(c), cnt(cnt){}
};

int vis[maxn][maxn];    
int dir[] = {1,-1, 2,-2};
int r1, c1, r2, c2;                //起点、终点的坐标 

int BFS(int x1, int y1, int x2, int y2);

int main(){
    //freopen("input.txt", "r", stdin);
    char s1[2], s2[2];
    while(cin >> s1 >> s2){
        r1 = s1[1] - '0';
        c1 = s1[0] - 'a' + 1;
        r2 = s2[1] - '0';
        c2 = s2[0] - 'a' + 1;
        cout << "To get from " << s1 << " to " << s2 << " takes " << BFS(r1, c1, r2, c2) << " knight moves."<< endl;
    } 
    
    return 0;
}

int BFS(int x1, int y1, int x2, int y2){
    
    memset(vis, 0, sizeof(vis));
    queue<Point> q;
    q.push(Point(x1, y1, 0));
    vis[x1][y1] = 1;
    
    while(!q.empty()){
        Point u = q.front();    q.pop();
        if(u.r == r2 && u.c == c2)
            return u.cnt;
            
        for(int i=0; i<4; i++){                //将可走的结点加入队列 
            for(int j=0; j<4; j++){
                if(i != j && -dir[i] != dir[j]){
                    Point v(u.r+dir[i], u.c+dir[j], u.cnt+1);
                    if(v.r>=1 && v.r<=8 && v.c>=1 && v.c<=8 && vis[v.r][v.c]==0){
                        q.push(v);
                        vis[v.r][v.c] = 1;
                    }
                }
            }
        }
    }
}

 

posted @ 2016-11-06 11:24  淡蓝色光  阅读(181)  评论(0编辑  收藏  举报