ZOJ 1649 Resuce (BFS)

9 篇文章 0 订阅
Rescue

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)


Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.


Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."


Sample Input

7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........


Sample Output

13


题目的意思应该很明确了,从r点出发,到达a点,要求求出到达a点的最小时间。如果经过的网格有守卫,则要杀死守卫,这样的话会多花一秒的时间。

又是迷宫问题,又是求最优解的问题,毫无疑问我们要用BFS来做。

vis数组保存了到达当前点所要花费的最小时间。

因为从起点到终点的路径不止一条,每次又要保证最终到达终点的这个路径是花费时间最短的,所以每次扩展一个点,如果从当前位置扩展之后的时间当前扩展点的vis值大,也就是到达当前扩展点的时间比之前某步骤到达此扩展点的时间长,那么我们就不用扩展这个点,不用入队列,即不把他当做我们路径中的一部分。

用min1保存到达终点的最小值,初始化一个最大值,如果没有更新过,那么证明到达不了终点,即输出题目中不可能到达的情况。



代码如下:



先贴一个用DFS超时的代码

//DFS//
/*
#include<stdio.h>
#include<string.h>
char map[220][220];
bool vis[220][220];
int x_move[4] = {-1, 0, 1, 0};
int y_move[4] = {0, 1, 0, -1};
int N,M;
int s1,s2;
int e1,e2;
int min;
int sign;
int is_ok(int x,int y)
{
	if(map[x][y]=='.'||map[x][y]=='x')
		return 1;
	else
		if(map[x][y]=='#')
			return 0;
}
void dfs(int s11,int s22,int count)
{
	int tx,ty;
	int i,j,k;
	if(s11==e1&&s22==e2)
	{
		if(count<min)
			min=count;
		sign=1;
		return ;
	}
	for(i=0;i<4;i++)
	{
		tx=s11+x_move[i];
		ty=s22+y_move[i];
		if(tx<1||tx>N||ty<1||ty>M)            //判断是否超出边界//
			continue ;	
		if(vis[tx][ty]==0&&is_ok(tx,ty))
		{
			vis[tx][ty]=1;
			if(map[tx][ty]=='x')
				count+=2;
			else
				count+=1;
			dfs(tx,ty,count);
			vis[tx][ty]=0;
			if(map[tx][ty]=='x')
				count-=2;
			else
				count-=1;
		}
	}
	return ;
}
int main()
{
	//int min;
	int i,j,k;
	while(scanf("%d%d",&N,&M)!=EOF)
	{
		sign=0;
		min=9999999;
		getchar();
		for(i=1;i<=N;i++)
			scanf("%s",map[i]+1);
		for(i=1;i<=N;i++)
			for(j=1;j<=M;j++)
			{
				if(map[i][j]=='r'){s1=i;s2=j;}
				if(map[i][j]=='a'){e1=i;e2=j;}
			}
		memset(vis,0,sizeof(vis));
		vis[s1][s2]=1;
		dfs(s1,s2,0);
		if(sign==1)
			printf("%d\n",min);
		else
			printf("Poor ANGEL has to stay in the prison all his life.\n");

	}
	return 0;
}




BFS

#include<iostream>
#include<queue>
#include<limits.h>
#include<stdio.h>
using namespace std;
typedef struct node
{
	int x,y;
	int times;
}node;
queue<node> fuck;
int N,M;
int min1;
char map[210][210];
int  vis[210][210];
int x_move[4] = {-1, 0, 1, 0};
int y_move[4] = {0, 1, 0, -1};
int is_ok(int x,int y)
{
	if(map[x][y]!='#')
		return 1;
	else
		return 0;
}
void BFS()
{
	int i;
	node pos;
	node res;
	int tx,ty;
	while(!fuck.empty())
	{
		pos=fuck.front();
		fuck.pop();
		res.x=pos.x;
		res.y=pos.y;
		res.times=pos.times;
		for(i=0;i<4;i++)
		{
			tx=res.x+x_move[i];
			ty=res.y+y_move[i];
			if(tx<1||tx>N||ty<1||ty>M)
				continue;
			if(is_ok(tx,ty))
			{
				if(map[tx][ty]=='a')
				{
					min1=min1<res.times+1?min1:res.times+1;
					continue;
				}
				if(map[tx][ty]=='.'&&(res.times+1)<vis[tx][ty])
				{
					vis[tx][ty]=res.times+1;
					pos.times=res.times+1;
					pos.x=tx;
					pos.y=ty;
					fuck.push(pos);
				}
				if(map[tx][ty]=='x'&&(res.times+2)<vis[tx][ty])
				{
					vis[tx][ty]=res.times+2;
					pos.times=res.times+2;
					pos.x=tx;
					pos.y=ty;
					fuck.push(pos);
				}

			}
		}

	}
}
int main()
{ 
	int i,j;
	node temp;
	while(scanf("%d%d",&N,&M)!=EOF)
	{
		for(i=1;i<=N;i++)
			for(j=1;j<=M;j++)
				vis[i][j]=INT_MAX;

		getchar();
		for(i=1;i<=N;i++)
		{
			for(j=1;j<=M;j++)
			{
				scanf("%1c",&map[i][j]);
				if(map[i][j]=='r')
				{
					temp.x=i;
					temp.y=j;
					temp.times=0;
					fuck.push(temp);
				}
			}
			getchar();
		}
		vis[temp.x][temp.y]=0;
		min1=INT_MAX;
		BFS();
		if(min1==INT_MAX)
			printf("Poor ANGEL has to stay in the prison all his life.\n");
		else
			printf("%d\n",min1);
	}
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值