• 洛谷P1379 八数码难题 题解 A*搜索


    题目链接:https://www.luogu.com.cn/problem/P1379

    一般搜索:

    #include <bits/stdc++.h>
    using namespace std;
    int tmp[3][3], dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
    int parse(int s, int d) {
        for (int i = 0; i < 3; i ++) {
            for (int j = 0; j < 3; j ++) {
                tmp[i][j] = s % 10;
                s /= 10;
            }
        }
        int x, y;
        for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) if (!tmp[i][j]) x = i, y = j;
        int xx = x + dir[d][0], yy = y + dir[d][1];
        if (xx >= 0 && xx < 3 && yy >= 0 && yy < 3) {
            swap(tmp[x][y], tmp[xx][yy]);
            int res = 0, t = 1;
            for (int i = 0; i < 3; i ++) {
                for (int j = 0; j < 3; j ++) {
                    res += tmp[i][j] * t;
                    t *= 10;
                }
            }
            return res;
        }
        else return -1;
    }
    map<int, int> mp;
    int a;
    queue<int> que;
    int main() {
        cin >> a;
        if (a == 123804765) {
            puts("0");
            return 0;
        }
        mp[a] = 0;
        que.push(a);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            int dis = mp[u];
            for (int i = 0; i < 4; i ++) {
                int v = parse(u, i);
                if (v == -1 || mp.find(v) != mp.end()) continue;
                mp[v] = dis + 1;
                if (v == 123804765) {
                    cout << dis + 1 << endl;
                    return 0;
                }
                que.push(v);
            }
        }
        return 0;
    }
    

    A星搜索:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int target[3][3] = { 1, 2, 3, 8, 0, 4, 7, 6, 5 };
    struct Matrix {
        int a[3][3];
        int to_int() {
            int res = 0;
            for (int i = 0; i < 3; i ++)
                for (int j = 0; j < 3; j ++)
                    res = res * 10 + a[i][j];
            return res;
        }
    };
    int h(Matrix a) {   // 返回有多少个位置和终点不一样
        int cnt = 0;
        for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++)
            if (a.a[i][j] != target[i][j]) cnt ++;
        return cnt;
    }
    struct Node {
        Matrix a;   // 当前格子的状态
        int step;   // 一共走了多少步
        bool operator < (Node b) const {
            return step + h(a) > b.step + h(b.a);
        }
    };
    bool check(Node u) {
        for (int i = 0; i < 3; i ++)
            for (int j = 0; j < 3; j ++)
                if (u.a.a[i][j] != target[i][j])
                    return false;
        return true;
    }
    priority_queue<Node> que;
    char s[11];
    int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
    set<int> st;
    int main() {
        scanf("%s", s);
        Node u;
        for (int i = 0; i < 3; i ++)
            for (int j = 0; j < 3; j ++)
                u.a.a[i][j] = s[i*3+j] - '0';
        u.step = 0;
        que.push(u);
        while (!que.empty()) {
            Node u = que.top();
            que.pop();
            if (check(u)) {
                printf("%d
    ", u.step);
                return 0;
            }
            int x, y;
            for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++)
                if (u.a.a[i][j] == 0) x = i, y = j;
            for (int i = 0; i < 4; i ++) {
                Node v = { u.a, u.step+1 };
                int xx = x + dir[i][0], yy = y + dir[i][1];
                if (xx >= 0 && xx < 3 && yy >= 0 && yy < 3) {
                    swap(v.a.a[x][y], v.a.a[xx][yy]);
                    int val = v.a.to_int();
                    if (st.count(val)) continue;
                    st.insert(val);
                    que.push(v);
                }
            }
        }
        puts("-1"); // 按照题目保证不会出现这种情况
        return 0;
    }
    
  • 相关阅读:
    HDU 1102 Constructing Roads
    HDU 1285 确定比赛名次。
    最小生成树 HDU 各种畅通工程的题,prim和kru的模板题
    HDU Jungle Roads 1301 最小生成树、
    并查集小结(转)
    HDU hdu 2094 产生冠军 拓扑排序 判定环
    模运算(转)
    拓扑排序(主要是确定环和加法) HDU 2647 Reward
    HDU 1372 Knight Moves 简单BFS
    用计算机模型浅析人与人之间沟通方式 (一)如何谈话
  • 原文地址:https://www.cnblogs.com/quanjun/p/13687865.html
Copyright © 2020-2023  润新知