BZOJ#1054[HAOI2008]移动玩具
[HAOI2008]移动玩具
思路:
把矩阵压缩,然后bfs即可
代码:
#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
const int N = 5;
int get(int x, int y) {
return x * 4 + y;
}
pair<int, int> moves[] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; //ULRD
int vis[1 << 16];
struct T {
int state, step;
};
pair<int, int> get2(int x) {
return {x / 4, x % 4};
}
char s[N][N], t[N][N];
void solve(int Case) {
for (int i = 0; i < 4; i++) cin >> s[i];
for (int i = 0; i < 4; i++) cin >> t[i];
T start = {0, 0};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int k = get(i, j);
if (s[i][j] == '1') {
start.state |= (1LL << k);
}
}
}
int target = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int k = get(i, j);
if (t[i][j] == '1') {
target |= (1LL << k);
}
}
}
if (start.state == target) {
cout << 0 << nline;
return;
}
queue<T> q;
q.push({start});
while (q.size()) {
auto [ns, step] = q.front();
q.pop();
for (int i = 0; i < 16; i++) {
if (ns >> i & 1) {
auto [x, y] = get2(i);
for (auto [dx, dy] : moves) {
int tx = x + dx, ty = y + dy;
int tk = get(tx, ty);
if (tx >= 0 and tx<4 and ty >= 0 and ty < 4 and (ns >> tk & 1) == 0) {
int news = ns - (1LL << i);
news += (1LL << tk);
if (!vis[news]) {
vis[news] = step + 1;
if (news == target) {
cout << step + 1 << nline;
return;
}
q.push({news, step + 1});
}
}
}
}
}
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
// for (cin>>_, Case = 1; Case <= _; Case++)
solve(Case);
return 0;
}