题目大意:一般的搜索问题,用BFS能够0ms解决。有剩余时限让你去走迷宫,有一个特殊的东西可以让你的剩余时间重置。
具体的要求是:
1. We can assume the labyrinth is a 2 array.(二维迷宫)
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.(不能走墙)
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.(刚好在剩余0S走出也不行)
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.(刚好在0s重置时间也不行)
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.(你可以使用重置若干次,不过在我的代码当中,是没考虑,不知道是不是测试数据太弱了,就那么AC了。)
6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.(一走到该道具,剩余时间立刻重置,不需要考虑时间)
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.(不能走墙)
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.(刚好在剩余0S走出也不行)
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.(刚好在0s重置时间也不行)
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.(你可以使用重置若干次,不过在我的代码当中,是没考虑,不知道是不是测试数据太弱了,就那么AC了。)
6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.(一走到该道具,剩余时间立刻重置,不需要考虑时间)
测试数据:
3 3 3 2 1 1 1 1 0 1 1 3 4 8 2 1 1 0 1 1 1 0 1 0 4 1 1 0 4 1 1 0 0 0 0 0 0 1 1 1 1 4 1 1 1 3 5 8 1 2 1 1 1 1 1 4 1 0 0 0 1 0 0 1 1 4 1 0 1 1 0 1 1 0 0 0 0 3 0 1 1 1 4 1 1 1 1 1
4 -1 13
以下是我的AC代码:一般的BFS模板根据条件改编
#include<iostream>
#include <queue>
#include <cstring>
using namespace std;
short map[10][10], vis[10][10];
int Div[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
int n, m;
int sx, sy, ex, ey;
int times = -1;
struct pos
{
int x;
int y;
int times;
int Time;
friend bool operator <(pos a, pos b)//使用优先队列,使得剩余时间最多的先出队
{
return a.Time<b.Time;
}
};
void bfs()
{
memset(vis, 0, sizeof (vis));
priority_queue<pos>q;
pos p, mid;
p.x = sx;
p.y = sy;
p.times = 0;
p.Time = 6;
q.push(p);
vis[sx][sy] = 1;
while (!q.empty())
{
p = q.top();
q.pop();
if (p.x == ex&&p.y == ey&&p.Time > 0)
{
times = p.times;
return;
}
if (p.Time == 1)//这个是针对0秒不可行,即当剩余时间为1S是还没走出,那永远不可以。
continue;
for (int i= 0; i < 4; i++)//这边加入一个判断,是为了判断该点附近有没有时间重置的地点。
{
mid = p;//具体理解看第三个测试数据吧,还好测试数据给的良心,不然完全不会想到。
mid.x = p.x + Div[i][0];//道行还是太浅了。
mid.y= p.y + Div[i][1];
if (mid.x >= 1 && mid.x <= n&&mid.y <= m&&mid.y >= 1 && map[mid.x][mid.y] == 4&&p.Time<5)
{
mid.Time = 6;
mid.times++;//本来想解释一下,但发现不会解释,看不懂的还是看测试数据三理解吧
q.push(mid);
p.Time = 5;
p.times += 2;
break;
}
}
for (int i = 0; i < 4; i++)
{
mid = p;
mid.x = p.x + Div[i][0];
mid.y = p.y + Div[i][1];
mid.times++;
mid.Time--;
if (mid.x>n || mid.x<1 || mid.y>m || mid.y < 1||!map[mid.x][mid.y]||vis[mid.x][mid.y])
continue;
if (map[mid.x][mid.y] == 4)
{
vis[mid.x][mid.y] = 1;
mid.Time = 6;
q.push(mid);
continue;
}
else
{
vis[mid.x][mid.y] = 1;
q.push(mid);
}
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
cin >> n >> m;
times = -1;
for (int i = 1; i <= n;i++)
for (int j = 1; j <= m; j++)
{
cin >> map[i][j];
if (map[i][j] == 2)
{
sx = i; sy = j;
}
if (map[i][j] == 3)
{
ex = i; ey = j;
}
}
bfs();
cout << times << endl;
}
}