C-小d和超级泡泡堂

C-小d和超级泡泡堂_牛客小白月赛70 (nowcoder.com)
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小 D 在某天醒来发现自己穿越到了小游戏《超级泡泡堂》的世界,他得到了一份地图,一个技能和三个提示。

这个地图共有 n 行 m 列,行从上到下按 1 ~ n 编号,列从左到右按 1 ~ m 编号。地图上存在空地、石头、杂草。
 

这个技能是在自己当前所在位置放置一个不会对自己造成影响的炸弹,炸弹爆炸会产生火焰,火焰会向上下左右四个方向蔓延,如果火焰的蔓延方向上为空地,则会直接蔓延到空地并且在空地上开始继续蔓延,如果火焰的蔓延方向上为杂草,则会将杂草烧掉使其变为空地, 并且在新产生的空地继续蔓延,如果火焰蔓延方向上为石头,则无法继续朝这个方向蔓延,当然,火焰不可能蔓延到地图外。


三个提示分别是:

1、你可以向上下左右四个方向移动,如果那个方向上不是石头且不会移动到地图外。

2、你的技能只能使用一次。

3、你只有正确回答你最多能通过使用技能使多少杂草地变为空地才能够回到现实世界。
 

小 D 非常想要回去现实世界玩原神,请你帮助他计算出他最多能通过使用技能使多少杂草地变为空地。

 注:当火焰蔓延到另一个地方将要继续蔓延时,蔓延方式等同于在该地方重新放置炸弹。 \textbf{ 注:当火焰蔓延到另一个地方将要继续蔓延时,蔓延方式等同于在该地方重新放置炸弹。 } 注:当火焰蔓延到另一个地方将要继续蔓延时,蔓延方式等同于在该地方重新放置炸弹。

输入

复制

4 4
..!.
.@.#
!##!
#!!!

输出

复制

2

 第一版代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int MAXN = 1e3+10;

char mp[MAXN][MAXN];
bool vis[MAXN][MAXN];

int find(int x,int y,int n,int m)
{
    int ans = 0;
    queue<PII> Q;
    Q.push({x,y});
    mp[x][y] = '#';
    while(!Q.empty())
    {
        x = Q.front().first;
        y = Q.front().second;
        Q.pop();
        if(mp[x][y] == '!') ans++;
        if(y+1<=m && mp[x][y+1]!='#' && !vis[x][y+1])
        {
            Q.push({x, y+1});
            vis[x][y+1] = true;
        }
        if(x+1<=n && mp[x+1][y]!='#' && !vis[x+1][y])
        {
            Q.push({x+1, y});
            vis[x+1][y] = true;
        }
        if(y-1>=1 && mp[x][y-1]!='#' && !vis[x][y-1])
        {
            Q.push({x, y-1});
            vis[x][y-1] = true;
        }
        if(x-1>=1 && mp[x-1][y]!='#' && !vis[x-1][y])
        {
            Q.push({x-1, y});
            vis[x-1][y] = true;
        }
    }
    return ans;
}

int main()
{
    int x,y;
    int n,m;cin>>n>>m;getchar();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char ch;cin>>ch;
            mp[i][j] = ch;
            if(ch == '@')
            {
                x = i; y = j;
            }
        }
    }
    cout<<find(x,y,n,m);
    return 0;
}

第二版代码:

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
typedef pair<int,int> pii;
typedef long long ll;
typedef double db;
const int MAXN = 1e3+10;
char s[MAXN][MAXN];
int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};
int ans,n,m;
void bfs(int i,int j)
{
    if(i<1||j<1||i>n||j>m||s[i][j]=='#') return;
    if(s[i][j]=='!') ans++;
    s[i][j]='#';
    rep(k,0,3){
        bfs(i+dx[k],j+dy[k]);
    }
}
int main()
{
    cin>>n>>m;
    rep(i,1,n) scanf("%s",&s[i][1]);
    rep(i,1,n){
        rep(j,1,n){
            if(s[i][j]=='@') bfs(i,j);
        }
    }
    cout<<ans<<endl;
}

咳咳,说来惭愧,比赛开始做不出这题原因竟是读题不准,然后我还发现原来我写过bfs,第一版代码有点繁琐,另外要注意边界情况,其实第二版代码坐标数组早早写过,但当时没想这么写0.0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值