牛客网 - 小乐乐打游戏

链接:https://ac.nowcoder.com/acm/contest/301/G
来源:牛客网

时间限制: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!"。
 

输入

3 3
F..
#S#
#.E

输出

PIG PIG PIG!

前言:

        自己做完这道题后,在网上搜了下,看看有没有其他新颖的算法值得学习的,看了一圈,发现大部分人都是直接用曼哈顿距离来简化问题了,好家伙,都默认火山和出口只有一个是吗,还是我做题太少了啊......

        那我这边就晒一下当火山,出口,入口数量都不限的情况的做法吧(四舍五入就是新的一道题了)

#include <iostream>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
struct ty {
    int des, round;
}a[1005][1005];
int de[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int main() {
    int n, m;
    while (cin >> n >> m) {
        memset(a, 0, sizeof(a));
        queue<pair<int, int>>mm;
        queue<pair<int, int>>huo;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                char s;
                cin >> s;
                if (s == 'F') a[j][i].des = -1, a[j][i].round = 0, huo.push({ j,i });
                else if (s == '#') a[j][i].des = -2;
                else if (s == 'E') a[j][i].des = 3;
                else if (s == '.') a[j][i].des = 0, a[j][i].round = 0;
                else if (s == 'S') mm.push({ j,i }), a[j][i].des = 0, a[j][i].round = 0;
            }
        }
        int t = 0, nowround = 0;
        while (!mm.empty() && !t) {
            while (!mm.empty()) {
                int x = mm.front().first, y = mm.front().second;
                if (a[x][y].round != nowround) break;
                mm.pop();
                if (a[x][y].des < 0) continue;
                for (int i = 0; i < 4; i++) {
                    int gox = x + de[i][0], goy = y + de[i][1];
                    if (gox<1 || gox>m || goy<1 || goy>n) continue;
                    if (a[gox][goy].des < 0) continue;
                    if (a[gox][goy].round != 0) continue;
                    if (a[gox][goy].des == 3) {
                        t = 1;
                        break;
                    }
                    a[gox][goy].round = nowround + 1;
                    mm.push({ gox,goy });
                }
            }
            while (!huo.empty()) {
                int x = huo.front().first, y = huo.front().second;
                if (a[x][y].round != nowround) break;
                huo.pop();
                for (int i = 0; i < 4; i++) {
                    int gox = x + de[i][0], goy = y + de[i][1];
                    if (gox<1 || gox>m || goy<1 || goy>n) continue;
                    if (a[gox][goy].des == -1) continue;
                    a[gox][goy].des = -1;
                    a[gox][goy].round = nowround + 1;
                    huo.push({ gox,goy });
                }
            }
            nowround++;
        }
        if (t) cout << "PIG PIG PIG!" << endl;
        else cout << "A! WO SI LA!" << endl;
    }
    return 0;
}

此外这道题盲目用曼哈顿来求是不太对的,很多网友有个特殊情况没考虑到.例如

3 3
F.E
#S#
###

        直接用曼哈顿来求,发现入口到出口的距离考虑上障碍物后是2,而火山到出口的距离也是2.如果按照网上一部分码友写的那样,这种情况是算成功的.但实际上是失败的,因为很明显就能看出,当"小乐乐"走到(1,2)处的"."处后,火山就蔓延到(1,2)点处,直接把"小乐乐"烧死了.死因:(小乐乐试图在岩浆里游泳)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值