1. 程式人生 > >迷宮+火山(兩次廣搜)

迷宮+火山(兩次廣搜)

連結:https://ac.nowcoder.com/acm/contest/302/E
來源:牛客網
 

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述

        小樂樂覺得學習太簡單了,剩下那麼多的時間好無聊,於是便想打遊戲。
        最近新出了一個特別火的遊戲,叫吃豬,小樂樂準備玩一玩。
        吃豬遊戲很簡單,給定一個地圖,大小為n*m,在地圖中會隨機出現一個火山口,只要小樂樂能逃離這個地圖,他便能吃豬! 
        但吃雞遠沒有那麼簡單:
        1.小樂樂每走一次只能上下左右四個方向中走一步。
        2.小樂樂每走一步,火山噴發的岩漿就會向四周蔓延一個格子,所有岩漿走過的地方都視為被岩漿覆蓋。
        3.小樂樂碰到岩漿就會死。
        4.地圖中還有很多障礙,使得小樂樂不能到達,但是岩漿卻可以把障礙融化。
        5.小樂樂只有走到題目給定的終點才算遊戲勝利,才能吃豬。
        小樂樂哪見過這場面,當場就蒙了,就想請幫幫他,告訴他是否能吃豬。

輸入描述:

多組樣例輸入

第一行給定n,m,(1 <= n, m <= 1000)代表地圖的大小。

接下來n行,每一行m個字元,代表地圖,對於每一個字元,如果是'.',代表是平地,'S'代表小樂樂起始的位置,
'E'代表終點,'#'代表障礙物,'F'代表火山口。

輸出描述:

輸出只有一行。如果小樂樂能吃豬,輸出"PIG PIG PIG!"。否則輸出"A! WO SI LA!"。

示例1

輸入

複製

3 3
F..
#S#
#.E

輸出

複製

PIG PIG PIG!

 思路:先對火山進行廣搜,用陣列記下到每個方格的時間,再對人進行廣搜,當人到某個方格的時間大於等於火山到這個方格的

時間,說明人可以走

程式碼:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
const int N=1005;
char map[N][N];
bool vis[N][N];
int t[N][N],step[N][N];
int s_x,s_y,e_x,e_y,f_x,f_y;
struct node{
	int x,y;
};
int Next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void GetMap()
{
    for(int i=0;i<n;i++)
	   for(int j=0;j<m;j++)
	    {
	    	cin>>map[i][j];
	    	if(map[i][j]=='S')
	    	{
	    		s_x=i;
	    		s_y=j;
			}
			if(map[i][j]=='E')
			{
				e_x=i;
				e_y=j;
			}
			if(map[i][j]=='F')
			{
				f_x=i;
				f_y=j;
			}
	    }
}
bool judge(int x,int y)
{
	if(x<0||y<0||x>=n||y>=m) return 0;
	if(vis[x][y]) return 0;
	return 1;
}
void bfs()
{
	memset(t,0,sizeof(t));
	memset(vis,0,sizeof(vis));
	queue<node> q;
	node r;
	r.x=f_x;
	r.y=f_y;
	q.push(r);
	vis[f_x][f_y]=1;
	while(!q.empty())
	{
		r=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			int xx=r.x+Next[i][0];
			int yy=r.y+Next[i][1];
			if(!judge(xx,yy)) continue;
			node z;
			z.x=xx;
			z.y=yy;
			q.push(z);
			t[xx][yy]=t[r.x][r.y]+1;
			vis[xx][yy]=1;
		}
	}
}
void BFS()
{
	memset(step,0,sizeof(step));
	memset(vis,0,sizeof(vis));
	queue<node> q;
	node r;
	r.x=s_x;
	r.y=s_y;
	q.push(r);
	vis[s_x][s_y]=1;
	int flag=0;
	while(!q.empty())
	{
		r=q.front();
		q.pop();
		if(r.x==e_x&&r.y==e_y)
		{
			flag=1;
			break;
		}
		for(int i=0;i<4;i++)
		{
			int xx=r.x+Next[i][0];
			int yy=r.y+Next[i][1];
			if(xx==e_x&&yy==e_y)
			{
				flag=1;
				break;
			}
			if(!judge(xx,yy)) continue;
			if(map[xx][yy]=='#') continue;
			if(t[xx][yy]<=step[r.x][r.y]+1) continue;
			node z;
			z.x=xx;
			z.y=yy;
			q.push(z);
			vis[xx][yy]=1;
			step[xx][yy]=step[r.x][r.y]+1;
		}
	}
	if(flag) 
	   cout<<"PIG PIG PIG!"<<endl;
	else
	   cout<<"A! WO SI LA!"<<endl;
}
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		GetMap();
		bfs();//先對火山進行遍歷 
	    BFS();//再對人進行遍歷 
	} 
	return 0;
 }