73 lines
1.7 KiB
C++
73 lines
1.7 KiB
C++
#pragma once
|
|
#include <bitset>
|
|
#include <queue>
|
|
#include <tuple>
|
|
#include <cstring>
|
|
#include "pushbox.h"
|
|
|
|
namespace Solve {
|
|
thread_local std::bitset<N> mp[N];
|
|
thread_local int dis[N][N][N][N];
|
|
thread_local std::queue<std::tuple<int, int, int, int>> qu;
|
|
|
|
inline int bfs(int px, int py, int bx, int by, int tx, int ty) {
|
|
std::memset(dis, 127, sizeof(dis));
|
|
while (!qu.empty())
|
|
qu.pop();
|
|
|
|
auto expand = [&](int npx, int npy, int nbx, int nby, int d) {
|
|
if (npx < 0 || npx >= N)
|
|
return;
|
|
if (npy < 0 || npy >= N)
|
|
return;
|
|
if (nbx < 0 || nbx >= N)
|
|
return;
|
|
if (nby < 0 || nby >= N)
|
|
return;
|
|
if (mp[npx][npy] == 0)
|
|
return;
|
|
if (mp[nbx][nby] == 0)
|
|
return;
|
|
if (npx == nbx && npy == nby)
|
|
return;
|
|
|
|
if (dis[npx][npy][nbx][nby] <= d)
|
|
return;
|
|
dis[npx][npy][nbx][nby] = d;
|
|
qu.emplace(npx, npy, nbx, nby);
|
|
};
|
|
|
|
expand(px, py, bx, by, 0);
|
|
|
|
while (!qu.empty()) {
|
|
auto [npx, npy, nbx, nby] = qu.front();
|
|
int d = dis[npx][npy][nbx][nby];
|
|
qu.pop();
|
|
|
|
if (nbx == tx && nby == ty)
|
|
return d;
|
|
|
|
expand(npx + 1, npy, nbx, nby, d + 1);
|
|
expand(npx - 1, npy, nbx, nby, d + 1);
|
|
expand(npx, npy + 1, nbx, nby, d + 1);
|
|
expand(npx, npy - 1, nbx, nby, d + 1);
|
|
if (npx + 1 == nbx && npy == nby)
|
|
expand(npx + 1, npy, nbx + 1, nby, d + 1);
|
|
if (npx - 1 == nbx && npy == nby)
|
|
expand(npx - 1, npy, nbx - 1, nby, d + 1);
|
|
if (npx == nbx && npy + 1 == nby)
|
|
expand(npx, npy + 1, nbx, nby + 1, d + 1);
|
|
if (npx == nbx && npy - 1 == nby)
|
|
expand(npx, npy - 1, nbx, nby - 1, d + 1);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
inline int solve(Maze q) {
|
|
for (int i = 0; i < N; ++i)
|
|
mp[i] = q.M[i];
|
|
return bfs(q.poi[POI_PERSON][0], q.poi[POI_PERSON][1]
|
|
, q.poi[POI_BOX][0], q.poi[POI_BOX][1], q.poi[POI_TARGET][0], q.poi[POI_TARGET][1]);
|
|
}
|
|
}; // namespace Solve
|