POJ_1915_Double BFS Knight Moves

POJ Knight Move 1915
/*
 * POJ_1915_Double BFS  Knight Moves
 * 
 * I really like this double bfs problem
 * 
 * Author : a_clay  2014/05/06
 */
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <deque>
#include <map>
#include <algorithm>

using namespace std;
const int N = 305;
int steps[N][N];
int vis[N][N];
struct Point {
    int x, y;
}st, ed;
int n;
bool ok(int x, int y) {
    if (0 <= x && x < n && 0 <= y && y < n) {
        return true;
    }
    return false;
}
int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[] = {2, -2, 2, -2, 1, -1, 1, -1};
deque<Point> Q;
int bfs() {
    memset(steps, 0, sizeof(steps));
    memset(vis, 0, sizeof(vis));
    vis[st.x][st.y] = 1;
    vis[ed.x][ed.y] = 2;
    if (st.x == ed.x && st.y == ed.y) return 0; // 特殊数据优化 
    Q.clear();
    Q.push_back(st);
    Q.push_back(ed);
    Point cur, nex;
    int x0, y0, nx, ny;
    while (!Q.empty()) {
        cur = Q.front();
        Q.pop_front();;
        x0 = cur.x;
        y0 = cur.y;
        for (int i = 0; i < 8; i++) {
            nx = x0 + dx[i];
            ny = y0 + dy[i];
            if (!ok(nx, ny)) continue;
            if (vis[nx][ny] == 0) {
                steps[nx][ny] = steps[x0][y0] + 1;
                vis[nx][ny] = vis[x0][y0];
                nex.x = nx;
                nex.y = ny;
                Q.push_back(nex);
            }
            else {
                if (vis[nx][ny] != vis[x0][y0]) {
                    return steps[nx][ny] + steps[x0][y0] + 1;
                }
            }
        }
    }
    return 0;
}
int main() {
    int T;
    cin >> T;
    while (T--) {
        scanf("%d", &n);
        scanf("%d%d", &st.x, &st.y);
        scanf("%d%d", &ed.x, &ed.y);
        cout << bfs() << endl;
    }
    return 0;
}

posted @ 2014-05-07 16:57  小尼人00  阅读(95)  评论(0编辑  收藏  举报