zoj 1649 Rescue

Rescue

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 52   Accepted Submission(s) : 18
Problem Description
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
 

Author
CHEN, Xue
 
 
题意:
 
         a代表天使,r代表朋友,.代表路,#代表墙,x代表警察队!让求从r所在的位置到a所在的位置的最小的时间!每走一步所用的时间为1分,当遇到警察的时候,要杀死警察才能往前走,杀死警察要用1分!
 
思路:
         让求的时间和让求最小的距离的方法一模一样,就是多了让判断能不能到达终点,和在碰到警察的时候加成2就行了!
 
代码:
 
/*
这道题就是比求最小步数多了一个有可能找不到最小步数,还有就是在固定一个的点需要浪费的时间会有固定的值,只需要将其特殊处理就行了! 
*/ 
#include 
#include 
#include 
#include 
using namespace std;
#define INF 0xfffffff
char map[205][205];
int x,y,ex,ey,ans;
int vis[205][205];
int dx[4]={0,1,-1,0};
int dy[4]={1,0,0,-1};
int n,m;
int flag;
struct node //结构体优先队列 
{
	int x,y,step;
	friend bool operator < (node a,node b)
	{
		return a.step>b.step;
	}
}a,temp;

int judge()//判断符合题意的条件 
{
	if(temp.x<1||temp.x>n)    return 0;
	if(temp.y<1||temp.y>m)	return 0;
	if(map[temp.x][temp.y]=='#')	return 0;
	if(vis[temp.x][temp.y]==1)  return 0;
	if(temp.step>=ans)	return 0;
	return 1;
}
 
void bfs()//广搜终点 
{
	a.x=x;//将起点放到结构体a中,然后以整体的方式放到结构体优先队列里面 
	a.y=y;
	a.step=0;
	memset(vis,0,sizeof(vis));//将标记数组清零 
	priority_queueq;//定义一个结构体优先队列 
	vis[x][y]=1;//将起点位置进行标记 
	q.push(a);//将结构体a中的元素整体放到结构体优先队列中 
	while(!q.empty())//如果队列中的元素不为空的话,就进行广搜 (因为要对顶部元素周围的元素进行搜索看是不是终点,所以队列不能为空) 
	{
		a=q.top();//将对顶元素赋值给结构体a进行广搜! 
		q.pop();//对顶元素出队列 
		for(int i=0;i<4;i++)//广搜的过程 
		{
			temp.x=a.x+dx[i];
			temp.y=a.y+dy[i];
			if(map[temp.x][temp.y]=='x')//如果只x则需要加2,因为他需要用一分钟杀死警队,还需要一分钟走路的时间 
			    temp.step=a.step+2;
			else //否则就只加一分钟走路的时间 
			temp.step=a.step+1;
			if(judge())//判断那个点符合要求,就进行下面的操作 
			{
				if(temp.x==ex&&temp.y==ey)//如果那个点就是终点,中介将步数赋给ans,进行输出 
				{
					  ans=temp.step;
					  flag=1;
				      return;
			    }//否则将其标记,并放到队列里面! 
			vis[temp.x][temp.y]=1;
			q.push(temp);
		    }
		}
	}
	
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		ans=INF;flag=0;//这道题因为有可能不能到达终点,所以需要用flag来标记一下,如果有终点,输出终点,否则输出那句话 
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=n;i++)//通过循环将n行m列的字符串存到二维数组里面 
		{
			getchar();//记住这个不敢忘 
			for(int j=1;j<=m;j++)
				{
				   scanf("%c",&map[i][j]);
				   if(map[i][j]=='r')//找起点 
				   {
				   	x=i;y=j;
				   }
				   else if(map[i][j]=='a')//找终点 
				   {
				   	ex=i,ey=j;
				   }
			    }
	    }
		bfs(); 
		if(flag==1)//要是能到达终点,则输出最短的路径 
		printf("%d\n",ans);
		else//如果没有路能够到达终点,则输出这句话! 
		printf("Poor ANGEL has to stay in the prison all his life.\n");
	}
	return 0;
}

      

你可能感兴趣的:(bfs)