• 「题解」洛谷 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 << '
    ';
            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
    ", 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;
    }
    
  • 相关阅读:
    python打包
    tkinter python(图形开发界面)
    Pyinstaller 打包exe文件 取消dos窗口(黑框框)
    PHP知识点(转载https://www.cnblogs.com/mapsxy/p/9977744.html)
    Java去除字符串中的空格
    开心
    原型链—— javascript
    ajax跨域jsonp —— javascript
    ajax异步 —— javascript
    this —— javascript
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13582249.html
Copyright © 2020-2023  润新知