小乐乐下象棋-牛客网

22 篇文章 0 订阅
8 篇文章 0 订阅

https://ac.nowcoder.com/acm/con链接:https://ac.nowcoder.com/acm/contest/301/G?&headNav=acm
来源:牛客网
 

题目描述

        小乐乐觉得学习太简单了,剩下那么多的时间好无聊,于是便想打游戏。
        最近新出了一个特别火的游戏,叫吃猪,小乐乐准备玩一玩。
        吃猪游戏很简单,给定一个地图,大小为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!

test/301/G?&headNav=acm

 

 

小乐乐先走,熔岩再扩散,然后小乐乐再走,熔岩再扩散。可以从样例中看出来

 

设 m点坐标(mx,my)

火山坐标(fx,fy);

这道题典型的bfs,只是加上一个判断,小乐乐第n步要走m点的时候,要判断该点是否被熔岩覆盖,判断方法:

根据火山熔岩的扩散方式,让m点的横坐标减去火山的横坐标,m的纵坐标减去火山的纵坐标,选出最大值max,就是m点被熔岩覆盖的所需要的步数,所以得出,如果n<=max,就可以走到m点,否则 不能进入队列

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
char a[1001][1001];
int b[1001][1001];
struct node
{
    int x,y;
    friend bool  operator ==(node x,node y)
    {
        if(x.x==y.x&&x.y==y.y) return true;
        else return false;
    }
} e,f,s;
 
int juge3(int x,int y,int n,int m,int bu)
{
    if(x<0)return 0;
    if(x>=n) return 0;
    if(y<0) return 0;
    if(y>=m) return 0;
    if(a[x][y]=='#') return 0;
    int mx=max(abs(x-f.x),abs(y-f.y));
     //if(mx+1<=bu) return 0;
    //printf("mx=%d   bu=%d\n",mx,bu);
    //bu++;
    if(bu<=mx) return 1;
    else
        return 0;
    //return 1;
}
int bfs(int n,int m)
{
    queue<node>st;
    st.push(s);
    memset(b,0,sizeof(b));
    a[s.x][s.y]='#';
    int c[4][2]{ 1,0, -1,0,  0,1,  0,-1  };
    while(!st.empty())
    {
        node m1=st.front();
        a[m1.x][m1.y]='#';
        st.pop();
      //  printf("%d   %d\n",m1.x,m1.y);
        for(int i=0;i<4;i++)
        {
            int x,y;
            x=m1.x+c[i][0];
            y=m1.y+c[i][1];
            node m2;
            if(juge3(x,y,n,m,b[m1.x][m1.y]))
            {
                b[x][y]=b[m1.x][m1.y]+1;
                a[x][y]='#';
                m2.x=x;
                m2.y=y;
                st.push(m2);
 
            }
            if(m2==e) return 5;
        }
    }
    return 0;
}
int main()
{
 
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        // getchar();
        for(int i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            for(int j=0;j<m;j++)
            {
 
 
                if(a[i][j]=='S')
                {
                    s.x=i;
                    s.y=j;
                }
                else if(a[i][j]=='E')
                {
                    e.x=i;
                    e.y=j;
                }
                else if(a[i][j]=='F')
                {
                    f.x=i;
                    f.y=j;
                }
            }
            //getchar();
        }
      // printf("aa  %d  %d      \n%d   %d      \n%d   %d  aa\n",s.x,s.y,e.x,e.y,f.x,f.y );
        int flag=bfs(n,m);
        if(flag==5) printf("PIG PIG PIG!");
        else printf("A! WO SI LA!");
        printf("\n");
    }
    return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值