zoukankan      html  css  js  c++  java
  • 洛谷P2324 [SCOI2005]骑士精神 题解 A*搜索

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

    解题思路:

    A* 搜索。

    (h(x)) 表示当前状态下有多少位置和目标状态不一样。

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int target[][5] = {
        1, 1, 1, 1, 1,
        0, 1, 1, 1, 1,
        0, 0, 2, 1, 1,
        0, 0, 0, 0, 1,
        0, 0, 0, 0, 0
    };
    struct Matrix {
        int a[5][5];
        int to_ll() {
            long long res = 0, t = 1;
            for (int i = 0; i < 25; i ++) {
                res += a[i/5][i%5] * t;
                t *= 3;
            }
            return res;
        }
    };
    int h(Matrix a) {
        int cnt = 0;
        for (int i = 0; i < 5; i ++)
            for (int j = 0; j < 5; 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);
        }
    };
    priority_queue<Node> que;
    set<long long> st;
    int T;
    char s[5][10];
    int dir[8][2] = { -1, -2, -1, 2, -2, -1, -2, 1, 1, -2, 1, 2, 2, -1, 2, 1 };
    inline bool in_map(int x, int y) {
        return  x >= 0 && x < 5 && y >= 0 && y < 5;
    }
    bool check(Node u) {
        for (int i = 0; i < 5; i ++)
            for (int j = 0; j < 5; j ++)
                if (u.a.a[i][j] != target[i][j])
                    return false;
        return true;
    }
    int main() {
        scanf("%d", &T);
        while (T --) {
            while (!que.empty()) que.pop();
            st.clear();
            for (int i = 0; i < 5; i ++) scanf("%s", s[i]);
            Node u;
            for (int i = 0; i < 5; i ++) for (int j = 0; j < 5; j ++) {
                if (s[i][j] == '*') u.a.a[i][j] = 2;
                else u.a.a[i][j] = s[i][j] - '0';
            }
            u.step = 0;
            bool flag = false;
            que.push(u);
            int cnt = 0;
            while (!que.empty()) {
                Node u = que.top();
                que.pop();
                if (check(u)) {
                    flag = true;
                    printf("%d
    ", u.step);
                    break;
                }
                if (u.step + h(u.a)-1 > 15) continue;   // 这句话最重要!!!
                int x, y;
                for (int i = 0; i < 5; i ++) for (int j = 0; j < 5; j ++)
                    if (u.a.a[i][j] == 2) x = i, y = j;
                for (int i = 0; i < 8; i ++) {
                    int xx = x + dir[i][0], yy = y + dir[i][1];
                    if (!in_map(xx, yy)) continue;
                    Node v = { u.a, u.step+1 };
                    swap(v.a.a[x][y], v.a.a[xx][yy]);
                    int val = v.a.to_ll();
                    if (st.count(val)) continue;
                    st.insert(val);
                    que.push(v);
                }
            }
            if (!flag) puts("-1");
        }
        return 0;
    }
    
  • 相关阅读:
    C# 代理与事件上(delegate)
    串口编程(SerialPort类)
    java提取QQ邮箱中的邮箱地址
    javascript 调用onclick动作的几种方式。
    python的一些扩展模块,关于Reserving的....
    [ZZ]硬件虚拟化漫谈
    Intel VTx 技术手册 目录
    VTx技术手册杂记
    关于磁盘分析的一些资料
    ReactOS下的Sysutils目录.
  • 原文地址:https://www.cnblogs.com/quanjun/p/13688334.html
Copyright © 2011-2022 走看看