LeetCode -- 773. 滑动谜题

发布时间 2023-07-21 11:35:05作者: 深渊之巅

 启发式搜索

 

class Solution {

struct Node {
    string str;
    int x, y;
    int val;
};

int n = 2, m = 3;
string e = "123450";

int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

int f(string str) {
    int res = 0;
    for(int i = 0; i < n; i ++ ) {
        for(int j = 0; j < m; j ++ ) {
            if(str[i * m + j] == '0' || e[i * m + j] == '0') continue;
            int cur = str[i * m + j], next = e[i * m + j];
            int dx = abs((cur - 1) / 3 - (next - 1) / 3);
            int dy = abs((cur - 1) % 3 - (next - 1) % 3);
            res += dx + dy;
        }
    }
    return res;
}

string update(string cur, int i, int j, int p, int q) {
    swap(cur[i * m + j], cur[p * m + q]);
    return cur;
}

public:
    int slidingPuzzle(vector<vector<int>>& board) {
        string s = "";
        int x = 0, y = 0;
        for(int i = 0; i < n; i ++ ) {
            for(int j = 0; j < m; j ++ ) {
                if(board[i][j] == 0) x = i, y = j;
                s += board[i][j] + '0';
            }
        }


        auto cmp = [&](Node& left, Node& right) {
            return left.val > right.val;
        };

        priority_queue<Node, vector<Node>, decltype(cmp)> q(cmp);
        unordered_map<string, int> mp;
        q.push({s, x, y, 0});
        mp[s] = 0;

        while(q.size()) {
            auto t = q.top();
            q.pop();
            if(t.str == e) return mp[t.str];

            for(int i = 0; i < 4; i ++ ) {
                int nx = t.x + dx[i], ny = t.y + dy[i];
                if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                string nstr = update(t.str, t.x, t.y, nx, ny);
                if(!mp.count(nstr) || mp[nstr] > mp[t.str] + 1) {
                    q.push({nstr, nx, ny, mp[t.str] + 1 + f(nstr)});
                    mp[nstr] = mp[t.str] + 1;
                }
            }
        }

        return -1;
    }
};