Nightmare
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.
Given the layout of the labyrinth and Ignatius' start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.
Here are some rules:
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.
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.
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.
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.
Given the layout of the labyrinth and Ignatius' start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.
Here are some rules:
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.
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.
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.
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.
Input
The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius' start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius' target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius' start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius' target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
Output
For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.
Sample Input
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
Sample Output
4 -1 13
写这道题,看到这道题我就恼火-_-#,做这道题的时候编译器竟然能突然出现错误,一直不重新编译,明明正确的代码,还是出现了错误的结果,害的我找了半天,还是感觉代码没有错,就开始怀疑编译器了,就给 Mzx 发过去在他电脑上测试,一测试,果然,我的编译器出错!真是醉了!
好了,说说这道题吧,题目大概的意思就是说,有一个人,在一个迷宫中,然后他身上有一个炸弹,炸弹初始时间是 6,他每次只能走一步,并且每走一步,炸弹的时间就减一,当时间减到 0 是炸弹会爆炸,问他能在炸弹爆炸前走出去不能,在这个迷宫中点的种类一共有 5 种,
0 代表该点是墙,不能走
1 代表是该点是路可以走
2 表示起始的位置
3 表示出口的位置
4 表示如果他走到该点,切炸弹时间不为0 ,那么他的炸弹时间就可以重置为 6
在这道题中,如果你不进行标记,那么得到的肯定是 TLE ,但是这些点都可以重复走,该怎么标记呢?其实你仔细想一下,如果他到了一个时间重置点以后,他肯定不会第二次到达,因为第二次到达后和第一次到达后的炸弹时间是一样的,并且还多走了几步,所以,你只需要标记时间重置点就行了
附上代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
int n,m,end_x,end_y,ans;
int Map[10][10];
int visit[10][10];
int dt[4][2] = {1,0,0,1,0,-1,-1,0};
struct point
{
int x,y;
int time;
int step;
};
int bfs(int cur_x,int cur_y)
{
queue<point> Q;
point t;
t.x = cur_x;
t.y = cur_y;
t.step = 0;
t.time = 6;
Q.push(t);
while(!Q.empty())
{
t = Q.front();
Q.pop();
if(t.x == end_x && t.y == end_y && t.time > 0) // 找到出口 且炸弹没爆炸,那么就结束搜索
{
break;
}
for(int i = 0;i < 4;i++)
{
int tx = t.x + dt[i][0];
int ty = t.y + dt[i][1];
if(tx >= 0 && tx < n && ty >= 0 && ty < m && Map[tx][ty] != 0 && !visit[tx][ty])
{
point pt;
pt.x = tx;
pt.y = ty;
pt.step = t.step + 1;
pt.time = t.time - 1;
if(Map[tx][ty] == 4 && pt.time > 0) // 到了时间重置点并且能够重置,那么就重置
{
pt.time = 6;
visit[tx][ty] = 1;
}
if(pt.time > 0) // 如果炸弹已经爆炸了,那么就不用再入队列中了
Q.push(pt);
}
}
}
if(!Q.empty())
{
while(!Q.empty())
{
Q.pop();
}
return t.step;
}
else
return -1;
}
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n >> m;
int begin_x,begin_y;
memset(visit,0,sizeof(visit));
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
scanf("%d",&Map[i][j]);
if(Map[i][j] == 2)
{
begin_x = i;
begin_y = j;
}
if(Map[i][j] == 3)
{
end_x = i;
end_y = j;
}
}
}
ans = bfs(begin_x,begin_y);
cout << ans << endl;
}
return 0;
}