思路:
很容易想到用搜索去做,并且很容易想到在搜箱子的同时要去搜索人能否到达。
并且两个搜索我们在搜索的同时可以看成是独立的。
人搜索能不能到用DFS并且不用回溯,这样速度会更快。因为对于同一点我们只要到一次就可以了,并不要求最短。所以不用回溯。
在搜索箱子能不能到的时候并没有考虑到重复通过一点的问题。但是时候看了题解才恍然大悟,例如在箱子堵住了唯一路口,但要向人那边前进的时候,就需要后退,让人进来,再前进,这时候就需要重复经过一个点,但这种情况下,人和箱子所处的状态以及位置则是唯一的,切记!!那这时候便用hash记录箱子和人的相关坐标 hash[][][][];
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
int map[10][10];
bool H[10][10][10][10];
int sx, sy, ex, ey, px, py;
int n, m;
int Div[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
bool vis[10][10];
struct box
{
int bx, by;
int px, py;
int h;
int steps;
bool friend operator<(box a, box b)
{
return a.steps + a.h>b.steps + b.h;
}
};
bool check(int x, int y)
{
if (x >= 0 && x < n&&y >= 0 && y < m&&map[x][y] != 1)
return true;
return false;
}
bool dfs(int sx, int sy, int ex, int ey)
{
if (sx == ex&&sy == ey)
return true;
for (int i = 0; i < 4; i++)
{
int x = sx + Div[i][0];
int y = sy + Div[i][1];
if (check(x, y) && !vis[x][y])
{
vis[x][y]=1;
if (dfs(x, y, ex, ey))
return true;
}
}
return false;
}
int bfs()
{
memset(H, 0, sizeof(H));
priority_queue<box> q;
box p, mid;
p.bx = sx;
p.by = sy;
p.px = px;
p.py = py;
p.steps = 0;
p.h = abs(p.bx - ex) + abs(p.by - ey);
q.push(p);
while (!q.empty())
{
p = q.top();
q.pop();
if (p.bx == ex&&p.by == ey)
return p.steps;
for (int i = 0; i < 4; i++)
{
mid = p;
mid.bx += Div[i][0];
mid.by += Div[i][1];
mid.px =mid.bx- Div[i][0];
mid.py = mid.by - Div[i][1];
int ppx = p.bx - Div[i][0];
int ppy = p.by - Div[i][1];
if (check(mid.bx, mid.by) && check(ppx, ppy)&&!H[p.bx][p.by][ppx][ppy])
{
memset(vis, 0, sizeof(vis));
vis[p.bx][p.by] = 1;
vis[p.px][p.py] = 1;
if (dfs(p.px, p.py, ppx, ppy))
{
H[p.bx][p.by][ppx][ppy] = 1;
mid.steps = p.steps + 1;
mid.h = abs(mid.bx - ex) + abs(mid.by - ey);
q.push(mid);
}
}
}
}
return -1;
}
int main()
{
int t;
cin >> t;
while (t--)
{
cin >> n >> m;
for (int i = 0; i < n;i++)
for (int j = 0; j < m; j++)
{
scanf("%d", &map[i][j]);
if (map[i][j] == 2)
{
sx = i;
sy = j;
}
if (map[i][j] == 3)
{
ex = i;
ey = j;
}
if (map[i][j] == 4)
{
px = i;
py = j;
}
}
cout << bfs() << endl;
}
}