hdu1401双向BFS

#include <iostream>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <stdio.h>
#include <stack>
#include <map>
#include <string>
#include <string.h>


using namespace std;
const int N = 28;

struct Node {
    int x;
    int y;

    Node() {};

    Node(int _x, int _y) : x(_x), y(_y) {}

    bool operator<(const Node &f) const {
        if (x == f.x) {
            return y < f.y;
        } else {
            return x < f.x;
        }
    }
};

int dir[4][2] = {{-1, 0},
                 {0,  -1},
                 {1,  0},
                 {0,  1}};
bool vis[9][9];
map<int, int> dist_fir, dist_sed;

int can_go(int x, int y) {
    return 1 <= x && x <= 8 && 1 <= y && y <= 8;
}

int call_hash(vector<Node> ps) {
    int sum = 0;
    for (int i = 0; i < 4; i++) {
        sum = sum * 8 + ps[i].x - 1;
        sum = sum * 8 + ps[i].y - 1;
    }
    return sum;
}

vector<vector<Node>> build(vector<Node> ps) {
    vector<vector<Node>> ans;
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < 4; i++) {
        vis[ps[i].x][ps[i].y] = true;
    }
    for (int i = 0; i < 4; i++) {
        for (int d = 0; d < 4; d++) {
            int nx = ps[i].x + dir[d][0];
            int ny = ps[i].y + dir[d][1];
            if (!can_go(nx, ny)) {
                continue;
            }
            if (!vis[nx][ny]) {//直接走
                vector<Node> nex(ps);
                nex[i].x = nx;
                nex[i].y = ny;
                sort(nex.begin(), nex.end());
                ans.push_back(nex);
            } else {
                nx += dir[d][0];
                ny += dir[d][1];
                if (can_go(nx, ny) && (!vis[nx][ny])) { //跳
                    vector<Node> nex(ps);
                    nex[i].x = nx;
                    nex[i].y = ny;
                    sort(nex.begin(), nex.end());
                    ans.push_back(nex);
                }
            }
        }
    }
    return ans;
}

bool bfs(vector<Node> one, vector<Node> two) {
    sort(one.begin(), one.end());
    sort(two.begin(), two.end());
    dist_fir.clear();
    dist_sed.clear();
    queue<vector<Node>> fis, sed;
    fis.push(one);
    sed.push(two);
    dist_fir[call_hash(one)] = 0;
    dist_sed[call_hash(two)] = 0;
    while ((!fis.empty()) || (!sed.empty())) {
        if (!fis.empty()) {
            vector<Node> cur = fis.front();
            int cur_h = call_hash(cur);
            fis.pop();
            if (dist_sed.find(cur_h) != dist_sed.end()) {
                return true;
            }
            if (dist_fir[cur_h] >= 4) {
                continue;
            }
            vector<vector<Node>> nex = build(cur);
            for (int idx = 0; idx < nex.size(); idx++) {
                int h = call_hash(nex[idx]);
                if (dist_fir.find(h) == dist_fir.end()) {
                    dist_fir[h] = dist_fir[cur_h] + 1;
                    fis.push(nex[idx]);
                }
            }
        }
        if (!sed.empty()) {
            vector<Node> cur = sed.front();
            int cur_h = call_hash(cur);
            sed.pop();
            if (dist_fir.find(cur_h) != dist_fir.end()) {
                return true;
            }
            if (dist_sed[cur_h] >= 4) {
                continue;
            }
            vector<vector<Node>> nex = build(cur);
            for (int idx = 0; idx < nex.size(); idx++) {
                int h = call_hash(nex[idx]);
                if (dist_sed.find(h) == dist_sed.end()) {
                    dist_sed[h] = dist_sed[cur_h] + 1;
                    sed.push(nex[idx]);
                }
            }
        }
    }
    return false;
}


int main() {
    ios::sync_with_stdio(false);
    Node nd;
    while (cin >> nd.x >> nd.y) {
        vector<Node> one, two;
        one.push_back(nd);
        for (int i = 1; i < 4; i++) {
            cin >> nd.x >> nd.y;
            one.push_back(nd);
        }
        for (int i = 0; i < 4; i++) {
            cin >> nd.x >> nd.y;
            two.push_back(nd);
        }
        if (bfs(one, two)) {
            cout << "YES" << endl;
        } else {
            cout << "NO" << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值