「题解」洛谷 P1379 八数码难题

题目

P1379 八数码难题

简化题意

给你一个八数码,问你最少几步可以移动到目标状态。类似下图。

思路

双向宽搜。
挺暴力的,感觉没啥需要讲的。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>

int p[10][5], cnt[10];
char s[10], t[10];
bool flag;
struct Node {
    char a[10];
};
std::queue<Node> q[2];
std::map<std::string, bool> m[2];

int find0(Node x) {
    for (int i = 1; i <= 9; ++i) {
        if (x.a[i] == '0') return i;
    }
}

void okay(Node x, int typ) {
    std::string bz = "";
    for (int i = 1; i <= 9; ++i) {
        bz += x.a[i];
    }
    if (!m[typ][bz]) {
        //std::cout << bz << '\n';
        m[typ][bz] = true;
        q[typ].push(x);
    }
}

void work(int typ) {
    int size = q[typ].size();
    while (size--) {
        Node u = q[typ].front();
        q[typ].pop();
        std::string bz = "";
        for (int i = 1; i <= 9; ++i) {
            bz += u.a[i];
        }
        if (m[typ ^ 1][bz] == true) {
            flag = 1;
            return;
        }
        int pos = find0(u);
        for (int i = 1; i <= cnt[pos]; ++i) {
            std::swap(u.a[pos], u.a[p[pos][i]]);
            okay(u, typ);
            std::swap(u.a[pos], u.a[p[pos][i]]);
        }
    }
}

void bfs() {
    int cnt = 0;
    Node c, d;
    std::string e = "", f = "";
    for (int i = 1; i <= 9; ++i) {
        c.a[i] = s[i];
        d.a[i] = t[i];
        e += s[i];
        f += t[i];
    }
    q[0].push(c), q[1].push(d);
    m[0][e] = 1, m[1][f] = 1;
	while (1) {
        ++cnt;
        //puts("qwq");
        if (q[0].size() < q[1].size()) work(0);
        else work(1);
        if (flag == true) {
            printf("%d\n", cnt - 1);
            return;
        }
    }
}

int main() {
    std::cin >> s + 1;
    t[1] = '1', t[2] = '2', t[3] = '3';
    t[4] = '8', t[5] = '0', t[6] = '4';
    t[7] = '7', t[8] = '6', t[9] = '5';
    cnt[1] = 2, cnt[2] = 3, cnt[3] = 2;
    cnt[4] = 3, cnt[5] = 4, cnt[6] = 3;
    cnt[7] = 2, cnt[8] = 3, cnt[9] = 2;
    p[1][1] = 2, p[1][2] = 4;
    p[2][1] = 1, p[2][2] = 3, p[2][3] = 5;
    p[3][1] = 2, p[3][2] = 6;
    p[4][1] = 1, p[4][2] = 5, p[4][3] = 7;
    p[5][1] = 2, p[5][2] = 4, p[5][3] = 6, p[5][4] = 8;
    p[6][1] = 3, p[6][2] = 5, p[6][3] = 9;
    p[7][1] = 4, p[7][2] = 8;
    p[8][1] = 5, p[8][2] = 7, p[8][3] = 9;
    p[9][1] = 6, p[9][2] = 8;
    bfs();
    return 0;
}
posted @ 2020-08-29 14:53  yu__xuan  阅读(162)  评论(0编辑  收藏  举报