您的位置:首页 > 其它

UVA11624大火蔓延的迷宫

2014-10-16 16:00 246 查看
题意:

给1个n*m的网格,上面有的点能走,有的点不能走(墙),然后有的点是火源,火源和人一样,每次都是上下左右四个方向蔓延,速度一样是1,火也不可以从墙上跨过去,给你人的起点,终点是只要走到边界就行,就是走出矩阵,问你最小逃生时间。

思路:

一开始小卡了一下,过了一会马上反应过来了,这个题算是基本的广搜题吧!我们想下他跟我们见过的最最基本的广搜有什么区别?是不是就是多了几个火源,而火源的作用是什么,是不是就是在蔓延的时候把一些能走的点变成不能走了,既然火源的速度和人一样,那么我们可以把火源和人全都放入队列<记住,要先把所有的火源放进去,最后在放人>,然后所有点(火源还有人)走过的点都不能再走了,就完事了呗!这个题目有很多方法,如果你想的话 还可以先处理火源,把每个点最早到达的火源的时间记录下来,用所有的火源把地图处理完了之后再跑广搜(这个是白书给出的思路),不过感觉写着比较麻烦,我的代码<一开始说的方法>在下面,具体细节可以看代码。



#include<queue>

#include<stdio.h>

#include<string.h>

#define N 1000 + 10

using namespace std;

typedef struct

{

int x ,y ,t ,mk;

}NODE;

NODE xin ,tou;

queue<NODE>q;

bool map

;

int R ,C ,dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};

bool ok(int x ,int y)

{

return x >= 1 && x <= R && y >= 1 && y <= C && !map[x][y];

}

int BFS()

{

while(!q.empty())

{

tou = q.front();

q.pop();

for(int i = 0 ;i < 4 ;i ++)

{

xin.x = tou.x + dir[i][0];

xin.y = tou.y + dir[i][1];

xin.t = tou.t + 1;

xin.mk = tou.mk;

if(xin.mk && (xin.x == 0 || xin.x == R+1 || xin.y == 0 || xin.y == C + 1))

return xin.t;

if(ok(xin.x ,xin.y))

{



map[xin.x][xin.y] = 1;

q.push(xin);

}

}

}

return -1;

}

int main ()

{

int i ,j ,Ans ,t ,mkx ,mky;

char str
;

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d" ,&R ,&C);

while(!q.empty())q.pop();

for(i = 1 ;i <= R ;i ++)

{

scanf("%s" ,str);

for(j = 0 ;j < C ;j ++)

{

if(str[j] == '.') map[i][j+1] = 0;

else if(str[j] == '#') map[i][j+1] = 1;

else if(str[j] == 'J')

{

map[i][j+1] = 1;

mkx = i ,mky = j + 1;

}

else

{

map[i][j+1] = 1 ,xin.x = i ;

xin.y = j + 1 ,xin.t = 0;

xin.mk = 0;

q.push(xin);

}

}

}

xin.x = mkx ,xin.y = mky ,xin.t = 0 ,xin.mk = 1;

q.push(xin);

/*

puts("***************");

while(!q.empty())

{

tou = q.front();

q.pop();

printf("%d %d %d %d**\n" ,tou.x ,tou.y ,tou.t ,tou.mk);

}

puts("**************"); */

Ans = BFS();

Ans == -1 ? puts("IMPOSSIBLE"):printf("%d\n" ,Ans);

}

return 0;

}



















内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: