- 墙只有15个,因此可以二进制状态枚举拆哪些墙,用dfs如果能走到终点,就统计答案的最小值
- 0.5处理:将所有坐标乘以二,并且0.5坐标还要+1;注意在坐标转移的时候也要*2才行;还有整个迷宫也要 *2;考虑原先0.5的时候墙的坐标是整数,现在人的坐标也是整数了,坐标转移的时候是判断不要 *2的走法有没有穿墙;数组大小也要乘二
- 要将所有墙上的每个点标记是哪个墙;
- 坐标转移判断:首先是范围;然后关于墙,是看方向以及是否穿墙;如果要走的点没有被走过,那么看要走的点是不是没有墙或者墙被拆了
- 由于二进制表示第几个墙,因此,地图要初始化为-1
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50;
int n, m, k;
int g[N][N];
int sx, sy, ex, ey;
bool st[N][N];
int ans;
int now;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
void dfs(int x, int y) {
if (x == ex && y == ey) {
int cc = 0, cct = now;
while (cct) {
if (cct & 1) cc ++ ;
cct >>= 1;
}
ans = min(ans, cc);
return ;
}
for (int d = 0; d < 4; ++ d) {
int nx = x + 2 * dx[d], ny = y + 2 * dy[d];
if (nx < 0 || nx > n || ny < 0 || ny > m) continue;
int qq = -1;
if (d <= 1 && g[x + dx[d]][y] != -1) {
qq = g[x + dx[d]][y];
}
if (d > 1 && g[x][y + dy[d]] != -1) {
qq = g[x][y + dy[d]];
}
if (!st[nx][ny]) {
if (qq == -1 || (now >> qq & 1)) {
st[nx][ny] = true;
dfs(nx, ny);
}
}
}
}
int main() {
int _; cin >> _;
while (_ -- ) {
cin >> n >> m >> k;
cin >> sx >> sy >> ex >> ey;
sx *= 2; sy *= 2; ex *= 2; ey *= 2;
sx ++ ; sy ++ ; ex ++ ; ey ++ ;
n *= 2; m *= 2;
memset(g, -1, sizeof g);
for (int i = 0; i < k; ++ i) {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
x1 *= 2; y1 *= 2; x2 *= 2; y2 *= 2;
if (x1 == x2) {
if (y1 > y2) swap(y1, y2);
for (int j = y1; j <= y2; ++ j) g[x1][j] = i;
} else {
if (x1 > x2) swap (x1, x2);
for (int j = x1; j <= x2; ++ j) g[j][y1] = i;
}
}
ans = 1e9;
for (int i = 0; i < (1 << k); ++ i) {
now = i;
memset(st, 0, sizeof st);
dfs(sx, sy);
}
cout << ans << endl;
}
}