题意:推箱子升级版,将三个箱子推到三个洞里,求最小步骤
分析:思路不难,就是处理起来,细节太多,纠结死了。一个八维的布尔数组判重,差点就MLE了
View Code
#include#include #include #define size 9 using namespace std; struct Node { int x, y; int Box[3][2];//记录三个箱子的位置 int step; char map[size][size]; } start; int dir[4][2] = { { 0, -1}, { 0, 1}, { -1, 0}, { 1, 0}}; char map[size][size]; int n, m; int T_map[size][size];//临时地图 bool visit[size][size][size][size][size][size][size][size];//八维数组,状态判重 Node pre, nex; bool is_finish(Node a)//判断是否每个箱子都入洞 { return (map[a.Box[0][0]][a.Box[0][1]] == '@' && map[a.Box[1][0]][a.Box[1][1]] == '@' && map[a.Box[2][0]][a.Box[2][1]] == '@' ); } bool check(int x, int y) { return (x >= 0 && x < n && y >= 0 && y < m); } int ans; char Tmap[size][size];//临时地图 void BFS() { queue Que; memset(visit, false, sizeof(visit)); Que.push(start); while (!Que.empty()) { pre = Que.front(); Que.pop(); if (is_finish(pre)) { ans = pre.step; return ; } for (int i = 0; i < 4; i ++) { //将前一个的地图copy到临时地图中 memcpy(Tmap, pre.map, sizeof(Tmap)); Node Tpre = pre; int xx = Tpre.x + dir[i][0]; int yy = Tpre.y + dir[i][1]; //判断是否入队 if (check(xx, yy) && Tmap[xx][yy] != '#' && !(visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]])) { //如果下一个点为箱子的话 if (Tmap[xx][yy] == '*') { int bx = xx + dir[i][0]; int by = yy + dir[i][1]; //判断箱子能否被推动 if (check(bx, by) && Tmap[bx][by] != '#' && Tmap[bx][by] != '*') { int ii = 0; //查找推动的是哪个箱子 for (ii = 0; ii < 3; ii ++) if (Tpre.Box[ii][1] == yy && Tpre.Box[ii][0] == xx) break; //推动后临时地图该点变为'*' Tmap[bx][by] = '*'; //原来的两个点都变成'.' Tmap[pre.x][pre.y] = '.'; Tmap[xx][yy] = '.'; //如果前一个点是'@'(洞)的话 if (T_map[pre.x][pre.y]) Tmap[pre.x][pre.y] = '@'; if (T_map[xx][yy]) Tmap[xx][yy] = '@'; Tpre.Box[ii][1] = by, Tpre.Box[ii][0] = bx; Tpre.x = xx, Tpre.y = yy; if ((visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]]))continue; } else continue; } nex.x = xx, nex.y = yy; for (int ii = 0; ii < 3; ii ++) { nex.Box[ii][0] = Tpre.Box[ii][0]; nex.Box[ii][1] = Tpre.Box[ii][1]; } //入队 nex.step = Tpre.step + 1; visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]] = true; memcpy(nex.map, Tmap, sizeof(nex.map)); Que.push(nex); } } } } int main() { while (scanf("%d%d", &n, &m) != EOF) { memset(T_map, 0, sizeof(T_map)); ans = -1; int numB = 0; for (int i = 0; i < n; i ++) { scanf("%s", map[i]); for (int j = 0; j < m; j ++) { if (map[i][j] == 'X') //记录起点 { start.x = i, start. y = j; start.step = 0; map[i][j] = '.'; } if (map[i][j] == '*') //记录箱子 { start.Box[numB][0] = i, start.Box[numB ++][1] = j; } if (map[i][j] == '@') //记录洞 { T_map[i][j] = 1; } } } memcpy(start.map, map, sizeof(start.map)); BFS(); printf("%d\n", ans); } return 0; }