题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1253
//这个题我MLE了好几次,就意识到剪枝的必要性 //改进后的代码 #include <iostream> #include <queue> using namespace std; int dir[6][3] = {{0,0,1},{0,1,0},{0,0,-1},{0,-1,0},{1,0,0},{-1,0,0}}; bool Map[50][50][50];//保存地图 struct Pos { int x, y, z, t; }; int main() { int k, a, b, c, time, wall; int x, y, z, i, j, p; bool flag; queue<Pos> q; Pos v, temp; scanf("%d", &k); while(k--) { flag = false; wall = 0; scanf("%d%d%d%d",&a, &b, &c, &time); for (i = 0; i < a; i++) for (j = 0; j < b; j++) for (p = 0; p < c; p++) { scanf("%d", &Map[i][j][p]); if (Map[i][j][p] != 0) wall ++; } if (a*b*c-wall < a+b+c-2 || time < a+b+c-3) {puts("-1"); continue;} //bfs while (!q.empty()) q.pop(); v.x = 0; v.y = 0; v.z = 0; v.t = 0;//起点 q.push(v);//起点入队 while (!q.empty()) { v = q.front(); q.pop(); if (v.t > time) break; if (v.x == a-1 && v.y == b-1 && v.z == c-1 && v.t <= time) { flag = true; break; } for (i = 0; i < 6; i++) { //搜索下一层的节点 x = v.x + dir[i][0]; y = v.y + dir[i][1]; z = v.z + dir[i][2]; if (!Map[x][y][z] && x >= 0 && x < a && y >= 0 && y < b && z >= 0 && z < c) { temp.x = x; temp.y = y; temp.z = z; temp.t = v.t+1; if (temp.t + a-1-temp.x + b-1-temp.y + c-1-temp.z > time) {//剪枝 Map[temp.x][temp.y][temp.z] = 1; continue; } q.push(temp); Map[temp.x][temp.y][temp.z] = 1;//标记掉已访问的点 } } } if (flag) printf("%d\n", v.t); else puts("-1"); } return 0; }