BFS +Astar TLE 60pts 求调
查看原帖
BFS +Astar TLE 60pts 求调
371409
Dangerise楼主2024/7/23 16:12
#include <bits/stdc++.h>
#include <cassert>
#include <cstdio>
#include <utility>
using namespace std;

#define int long long

inline int qread() {
    int ans = 0;
    char c = getchar();
    bool f = 0;
    while (c < '0' || c > '9') {
        if (c == '-') {
            f = 1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        ans = ans * 10 + c - '0';
        c = getchar();
    }
    if (f) {
        return -ans;
    } else {
        return ans;
    }
}

const int INF = INT_MAX;
const int N = 7;

struct V {
    int k, x, y;
};

inline bool eq(const V &a, const V &b) {
    return a.k == b.k && a.x == b.x && a.y == b.y;
}

inline bool operator<(const V &a, const V &b) {
    if (a.k == b.k) {
        if (a.x == b.x) {
            return a.y < b.y;
        } else {
            return a.x < b.x;
        }
    } else {
        return a.k < b.k;
    }
}

int a[N][N];

inline V press() {
    int k = 0, x, y;
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++) {
            k <<= 1;
            if (a[i][j] == 2) {
                x = i, y = j;
            } else {
                k |= a[i][j];
            }
        }
    }
    return {k, x, y};
}

inline void load(V v) {
    int x = v.k;
    for (int i = 5; i >= 1; i--) {
        for (int j = 5; j >= 1; j--) {
            a[i][j] = x & 1;
            x >>= 1;
        }
    }
    a[v.x][v.y] = 2;
}

V target;
int ta[N][N];
inline double h() {
    double h = 0;
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++) {
            if (ta[i][j] != a[i][j]) {
                h++;
            }
        }
    }
    return h * 1.3;
}

inline void dbg(const V &v) {
    int t[N][N];
    int x = v.k;
    for (int i = 5; i >= 1; i--) {
        for (int j = 5; j >= 1; j--) {
            t[i][j] = x & 1;
            x >>= 1;
        }
    }
    t[v.x][v.y] = 2;
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++) {
            printf("%lld ", t[i][j]);
        }
        putchar('\n');
    }
}

map<V, int> rec;

struct Q {
    V a;
    double f;
    int dis;
};

inline bool operator<(const Q &a, const Q &b) { return a.f > b.f; }

const int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
const int dy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int bfs(V start) {
    rec.clear();

    priority_queue<Q> q;
    q.push({start, 0, 0});
    rec.insert({start, 0});
    while (!q.empty()) {
        auto v = q.top().a;
        int dis = q.top().dis;
        int x = v.x, y = v.y;

        q.pop();

        load(v);

        assert(a[x][y] == 2);
        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx < 1 || nx > 5 || ny < 1 || ny > 5) {
                continue;
            }

            swap(a[x][y], a[nx][ny]);

            auto nv = press();
            assert(a[nv.x][nv.y] == 2);
            assert(nv.x == nx && nv.y == ny);
            if (eq(nv, target)) {
                return dis + 1;
            }
            if (dis + 1 == 15) {
                swap(a[x][y], a[nx][ny]);
                continue;
            }
            if (!rec.count(nv)) {
                rec.insert({nv, dis + 1});
                q.push({nv, dis + 1 + h(), dis + 1});
            }

            swap(a[x][y], a[nx][ny]);

            assert(eq(v, press()));
        }
    }
    return -1;
}

signed main() {
    int w[5] = {0, 1, 2, 4, 5};
    for (int i = 1; i <= 5; i++) {
        for (int j = w[i - 1] + 1; j <= 5; j++) {
            a[i][j] = 1;
        }
    }
    a[3][3] = 2;

    assert(sizeof(a) == sizeof(ta));
    memcpy(ta, a, sizeof(a));

    target = press();

    int t = qread();
    while (t--) {
        char c;
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                cin >> c;
                if (c == '0' || c == '1') {
                    a[i][j] = c - '0';
                } else {
                    a[i][j] = 2;
                }
            }
        }

        auto start = press();

        load(start);

        assert(eq(start, press()));

        int ans = bfs(start);

        printf("%lld\n", ans);
    }
    return 0;
}
2024/7/23 16:12
加载中...