有个网站专做品牌 而且价格便宜/百度搜索资源平台
解题思路
首先这个是广搜。
可以预处理出刚开始的箱子状态和终点。
那么 1×21×21×2 的情况怎么记录呢?
我们可以记录第一个格子,然后直接把第二个格子判断状态即可。
然后对于箱子的移动很麻烦,我们要用 dx,dydx,dydx,dy表示移动方向,dtdtdt表示移动后的状态。
最后直接搜就好了。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;const int dx[4][5] = { {}, { 0, 0, 0, -2, 1 }, { 0, 1, -1, 0, 0 }, { 0, 0, 0, 2, -1 } };
const int dy[4][5] = { {}, { 0, 1, -2, 0, 0 }, { 0, 0, 0, 2, -1 }, { 0, 1, -1, 0, 0 } };
const int dt[4][5] = { {}, { 0, 2, 2, 3, 3 }, { 0, 2, 2, 1, 1 }, { 0, 3, 3, 1, 1 } };char lyx[600][600];
bool flag = 0;
int n, m, h, t, tx, ty, v[600][600][4];struct c {int x, y, t, c;
} a[6000000];bool check(int x, int y, int t) {if (x < 1 || y < 1 || x > n || y > m || v[x][y][t] == 1)return 0;if (t == 1) {if (lyx[x][y] == '#' || lyx[x][y] == 'E')return 0;}if (t == 2) {if (lyx[x][y] == '#' || lyx[x][y + 1] == '#' || y + 1 > m)return 0;}if (t == 3) {if (lyx[x][y] == '#' || lyx[x + 1][y] == '#' || x + 1 > n)return 0;}return 1;
}void bfs() {h = 0, t = 1;while (h < t) {h++;for (int i = 1; i <= 4; i++) {int xx = a[h].x + dx[a[h].t][i], yy = a[h].y + dy[a[h].t][i], tt = dt[a[h].t][i];if (check(xx, yy, tt)) {t++;v[xx][yy][tt] = 1;a[t].x = xx, a[t].y = yy, a[t].t = tt, a[t].c = a[h].c + 1;if (xx == tx && yy == ty && tt == 1) {printf("%d\n", a[t].c);return;}}}}printf("Impossible\n");
}int main() {while (scanf("%d%d", &n, &m)) {memset(v, 0, sizeof(v));if (n == 0 && m == 0)break;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++) cin >> lyx[i][j];flag = 0;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (lyx[i][j] == 'O')tx = i, ty = j;if (lyx[i][j] == 'X' && !flag) {a[1].x = i, a[1].y = j, flag = 1;if (lyx[i][j + 1] == 'X')//状态2:横着躺着a[1].t = 2;else if (lyx[i + 1][j] == 'X')//状态3:竖着躺着a[1].t = 3;elsea[1].t = 1, v[i][j][a[i].t] = 1;//状态1:立着}}}bfs();}
}