Loading

八数码问题 双向BFS/Hsh链表存储

转自洛谷 作者EndSaH

#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
//const int maxn = 1e6 + 5;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std;

const  int mod1 = 1e5 + 7, mod2 = 1e6 + 9;
const int dx[] = { 0,0,1,-1 }, dy[] = { 1,-1,0,0 };

bool flag;
int ans;

struct Node {
    int key, step;
    bool head;
    Node* next;
    Node() { key = step = head = 0; next = NULL; }
}Hash[mod1+2];

struct CB {
    int value[3][3];
    int spx, spy, step;
    void init() {
        value[0][0] = 1;
        value[0][1] = 2;
        value[0][2] = 3;
        value[1][0] = 8;
        value[1][1] = 0;
        value[1][2] = 4;
        value[2][0] = 7;
        value[2][1] = 6;
        value[2][2] = 5;
        spx = 1;
        spy = 1;
    }
    bool operator ==(const CB& x)const {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (value[i][j] != x.value[i][j]) return false;
            }
        }
        return true;
    }
}start,goal;

bool   Querry(const CB& x, bool head) {
    int num = 0;
    int sum1, sum2;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) num = num * 10 + x.value[i][j];
    }
    sum1 = num % mod1, sum2 = num % mod2;
    if (!Hash[sum1].key) {
        Hash[sum1].key = sum2;
        Hash[sum1].head = head;
        Hash[sum1].step = x.step;
        return true;
    }
    if (Hash[sum1].key == sum2) {
        if (head != Hash[sum1].head) {
            flag = true;
            ans = x.step + Hash[sum1].step;
        }
        return false;
    }
    else {
        Node* now = &Hash[sum1];
        while (now->next) {
            now = now->next;
            if (now->key == sum2) {
                if (head != now->head) {
                    flag = true;
                    ans = now->step + x.step;
                }
                return false;
            }
        }
        Node* newnode = new Node;
        newnode->key = sum2;
        newnode->head = head;
        now->next = newnode;
        return true;
    }
}

void bfs() {
    queue<CB> q1;
    queue<CB> q2;
    start.step = goal.step = 0;
    q1.push(start);
    q2.push(start);
    while (1) {
        if (q1.size() > q2.size()) {
            CB now = q2.front();
            q2.pop();
            for (int i = 0; i < 4; i++) {
                int xx = now.spx + dx[i], yy = now.spy + dy[i];
                if (xx < 0 || xx >> 2 || yy < 0 || yy>2) continue;
                CB wib = now;
                wib.step = now.step + 1;
                wib.spx = xx, wib.spy = yy;
                swap(wib.value[xx][yy], wib.value[now.spx][now.spy]);
                if (Querry(wib, 0)) q2.push(wib);
                if (flag) return;
            }
        }
        else {
            CB now = q1.front();
            q1.pop();
            for (int i = 0; i < 4; i++) {
                int xx = now.spx + dx[i], yy = now.spy + dy[i];
                if (xx < 0 || xx>2 || yy < 0 || yy>2) continue;
                CB wib = now;
                swap(wib.value[xx][yy], wib.value[now.spx][now.spy]);
                wib.spx = xx, wib.spy = yy;
                wib.step = now.step + 1;
                if (Querry(wib, 1)) q1.push(wib);
                if (flag) return;
            }
        }
        if (flag) return;
    }
}

int main() {
    char ch;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j > 3; j++) {
            scanf("%c", &ch);
            if (ch == '0') start.spx = i, start.spy = j;
            start.value[i][j] = ch - '0';
        }
    }
    goal.init();
    if (goal == start) {
        printf("0");
    }
    else {
        bfs();
        printf("%d", ans);
    }
    return 0;
}

 

posted @ 2020-02-26 10:45  MQFLLY  阅读(214)  评论(0编辑  收藏  举报