题目连接:ヽ(ˋ▽ˊ)ノ
思路:每个点不止可以走一次, 而是可以可以从不同的方向到达一次,(wa了n多次)
code:
#include <stdio.h>
#include <string.h>
typedef struct
{
int x, y, count;
int xx, yy;
}node;
node step, quene[1000];
int map[10][10], used[4][10][10], visited[10][10];//用第三维标记方向
int m = 0, n = 0, X1 = 0, Y1 = 0, X2 = 0, Y2 = 0, flag1 = 0, flag2 = 0;//用flag1表明人能不能到箱子后面,flag2表明要走的步数
int dir[4][2] = {{-1, 0}, {0, 1}, {0, -1}, {1,0 }};
void dfs(int x, int y)
{
int i = 0, fx = 0, fy = 0;
if(x == X2 && y == Y2)
flag1 = 1;
if(flag1)
return;
for(i = 0; i<4; i++)
{
fx = x+dir[i][0]; fy = y+dir[i][1];
if(map[fx][fy] != 1 && !visited[fx][fy] && fx>-1 && fx<m+2 && fy>-1 && fy<n+2)
{
visited[fx][fy] = 1;
dfs(fx, fy);
}
}
}
void bfs()
{
int i = 0, x = 0, y = 0, fx = 0, fy = 0, count = 0, front = 0, rear = 0;
quene[rear++] = step;
while(front<rear)
{
x = quene[front].x; y = quene[front].y;
count = quene[front].count;
X1 = quene[front].xx; Y1 = quene[front++].yy;//改变人的位置
for(i = 0; i<4; i++)
{
flag1 = 0;
fx = x+dir[i][0]; fy = y+dir[i][1];//从x y推到fx fy
if(used[i][fx][fy]) continue;//下一个位置从这方向走过 不能再走
if(used[i][x][y])//表明当前点是从i方向推过来的 于是人一定在x y后面 可以向fx fy前进
{
flag1 = 1;
}
else
{
if(map[x+dir[3-i][0]][y+dir[3-i][1]] != 1)//3-i为当前方向i的相反方向 具体看dir数组
{
X2 = x+dir[3-i][0]; Y2 = y+dir[3-i][1];//当前箱子的反方向
visited[x][y] = 1;//箱子在的位置人不能走 标记
dfs(X1, Y1);//X1 Y1 人开始的点 X2 Y2 到达的点
memset(visited, 0, sizeof(visited));
}
}
if(flag1 && map[fx][fy] != 1)//如果人能到达该箱子后面和前进的点可走
{
step.x = fx; step.y = fy; step.count = count+1;
step.xx = x; step.yy = y;
used[i][fx][fy] = 1;
quene[rear++] = step;
}
if(flag1 && map[fx][fy] == 3)
{
flag2 = count+1;
return;
}
}
}
}
int main()
{
int i = 0, j = 0, t = 0;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
for(i = 0; i<m+2; i++)
{
for(j = 0; j<n+2; j++)
{
if(i == 0 || j == 0 || i == m+1 || j == n+1)
map[i][j] = 1;
else
{
scanf("%d",&map[i][j]);
if(map[i][j] == 4)
{
step.xx = i; step.yy = j;
}
if(map[i][j] == 2)
{
step.x = i; step.y = j; step.count = 0;
}
}
}
}
memset(used, 0, sizeof(used));
flag2 = 0;
bfs();
if(flag2)
printf("%d\n",flag2);
else
printf("-1\n");
}
return 0;
}