推箱子
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 120 Accepted Submission(s) : 46
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.

Input
Output
Sample Input
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
Sample Output
4
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
#include<queue>
int n, m, a[8][8],x1,y11,x2,y2,vis[8][8][8][8];vis标记每一状态的最小步数
int d[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
using namespace std;
struct node
{
int x1, y1, x2, y2, step;
};
queue<node> P;
void invt()
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
for (int h = 0; h < 8; h++)
vis[i][j][k][h] = 99999999;
}
int main()
{
int bfs();
int T; scanf_s("%d", &T);
while (T--)
{
invt();
scanf_s("%d%d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
scanf_s("%d", &a[i][j]);
if (a[i][j] == 4) x1 = i, y11 = j;
if (a[i][j] == 2) x2 = i, y2 = j;
}
node dc; dc.x1 = x1, dc.y1 = y11, dc.x2 = x2, dc.y2 = y2, dc.step = 0;
P.push(dc); vis[x1][y11][x2][y2] = 0;
int r=bfs();
printf("%d\n", r);
}
return 0;
}
int bfs()
{
int ans = 999999999; bool bb = 0;
while (!P.empty())
{
node dc; dc = P.front(); P.pop();
if (a[dc.x2][dc.y2] == 3)
{
ans = min(ans, dc.step);
bb = 1;
}
for (int i = 0; i < 4; i++)
{
int xx = dc.x1 + d[i][0], yy = dc.y1 + d[i][1];
if (xx >= 0 && xx < n&&yy >= 0 && yy < m&&a[xx][yy] != 1&&dc.step<vis[xx][yy][dc.x2][dc.y2])
{
if (xx == dc.x2&&yy == dc.y2)
{
int xx2 = dc.x2 + d[i][0], yy2 = dc.y2 + d[i][1];
if (xx2 >= 0 && xx2 < n&&yy2 >= 0 && yy2 < m&&a[xx2][yy2] != 1 && dc.step + 1 < vis[xx][yy][xx2][yy2])
{
node de; de.x1 = xx, de.y1 = yy, de.x2 = xx2, de.y2 = yy2, de.step = dc.step + 1;
P.push(de); vis[xx][yy][xx2][yy2] = de.step;
}
}
else
{
node de; de.x1 = xx, de.y1 = yy, de.x2 = dc.x2, de.y2 = dc.y2, de.step = dc.step;
P.push(de); vis[xx][yy][de.x2][de.y2] = de.step;
}
}
}
}
if (bb == 0) return -1;
return ans;
}