题目信息
题目传送门
解题思路
在这道题中,我们肯定会想到用bfs找最短路的想法。但是,并不是所有棋子的状态都是需要记录哒(这样就会TMLE得更多啦)。在棋子移动的过程中,除了和目标棋子换的时候,空的位置已知可以和别的棋子换,所以我们只需要记录空的位置和目标棋子的位置就ok啦。
代码实现(有错待改,注释待加)
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
const int dir[2][4] = {1, -1, 0, 0, 0, 0, 1, -1};
int a[N][N];
bool vis[N][N][N][N];
struct node {
int ex, ey, tx, ty;
int stp;
node() { }
node(int _ex, int _ey, int _tx, int _ty, int _stp) {
ex = _ex;
ey = _ey;
tx = _tx;
ty = _ty;
stp = _stp;
}
};
queue<node> Q;
int n, m, q;
inline bool in(node u) {
return 0 <= u.ex && u.ex < n && 0 <= u.ey && u.ey < m;
}
int main() {
cin >> n >> m >> q;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> a[i][j];
}
}
while (q--) {
int ex, ey, sx, sy, tx, ty;
cin >> ex >> ey >> sx >> sy >> tx >> ty;
if (sx == tx && sy == ty) {
cout << 0 << '\n';
continue;
}
memset(vis, false, sizeof vis);
vis[ex][ey][sx][sy] = true;
while (Q.size()) {
Q.pop();
}
Q.push(node(ex, ey, sx, sy, 0));
int res = -1;
while (Q.size() && res == -1) {
node u = Q.front();
Q.pop();
for (int i = 0; i < 4; ++i) {
node v = u;
++v.stp;
if (v.ex + dir[0][i] == v.tx && v.ey + dir[1][i] == v.ty) {
swap(v.ex, v.tx);
swap(v.ey, v.ty);
} else {
v.ex += dir[0][i];
v.ey += dir[1][i];
}
if (!in(v) || !a[v.ex][v.ey] || vis[v.ex][v.ey][v.tx][v.ty]) {
continue;
}
if (v.tx == tx && v.ty == ty) {
res = v.stp;
break;
}
vis[v.ex][v.ey][v.tx][v.ty] = true;
Q.push(v);
}
}
cout << res << '\n';
}
return 0;
}
|