链接:https://ac.nowcoder.com/acm/contest/301/G
来源:牛客网
题目描述
小乐乐觉得学习太简单了,剩下那么多的时间好无聊,于是便想打游戏。
最近新出了一个特别火的游戏,叫吃猪,小乐乐准备玩一玩。
吃猪游戏很简单,给定一个地图,大小为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!"。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
const int MAX_N = 1000;
char maze[MAX_N][MAX_N]; //迷宫
bool vis[MAX_N][MAX_N]; //标记当前位置是否被访问过
int n, m;
int xy[4][2] = { {1,0},{0,1},{-1,0},{0,-1} }; //移动方向
struct node
{
int x;
int y;
int steps;
}s,e,f; //定义起点,终点,火山为结构体变量
bool bfs()
{
memset(vis, 0, sizeof(vis)); //初始化标记数组
queue<node> que;
que.push(s);
vis[s.x][s.y] = 1; //起点入队并标记
while (que.size()) //一直循环到队列为空或者到达终点
{
node now = que.front();
que.pop(); //对头元素出队
if (now.x == e.x&&now.y == e.y)
return true; //如果到达终点,返回true
for (int i = 0; i < 4; i++) //向四个方向开始遍历
{
node next = now;
next.x += xy[i][0];
next.y += xy[i][1];
next.steps += 1; //记录下一步的位置和步数
if (!vis[next.x][next.y] && next.x >= 0 && next.x < n&&next.y >= 0 && next.y<m&&maze[next.x][next.y] != '#'&&abs(f.x - next.x) + abs(f.y - next.y)>next.steps)
{//步数即时间,火山到达这个位置需要的步数大于人需要的步数才可行
que.push(next);
vis[next.x][next.y] = 1; //将满足条件的位置入队并标记
}
}
}
return false;
}
int main()
{
while (~scanf("%d%d", &n, &m))
{
for (int i = 0; i<n; i++)
for (int j = 0; j < m; j++)
{
scanf(" %c", &maze[i][j]);
if (maze[i][j] == 'S')
s.x = i, s.y = j, s.steps = 0;
if (maze[i][j] == 'F')
f.x = i, f.y = j;
if (maze[i][j] == 'E')
e.x = i, e.y = j; //记录下起点,终点,火山的位置
}
if (bfs()) puts("PIG PIG PIG!");
else puts("A! WO SI LA!");
}
return 0;
}