第九届蓝桥杯A组省赛——全球变暖

【题目描述】
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000) 
以下N行N列代表一张海域照片。

照片保证第1行、第1列、第N行、第N列的像素都是海洋。

【输出格式】
一个整数表示答案。

【样例输入】

.......
.##....
.##....
....##.
..####.
...###.
.......

【样例输出】
1

想法:

错误做法:原来的岛的个数-剩下的岛的个数

例如

9
.........
.#######.
.###.###.
.###.###.
.........
.........
.........
..##.....
.........

结果是1

我的想法:对图进行bfs,将每个#标记为属于第几个岛,然后对图进行模拟淹没,将#变成‘.’(我的做法是先将和‘.'相邻的#变成$,然后在扫一遍图,将#变成‘.’),最后扫描整个图,看剩下哪些岛。

 

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
char ma[1500][1500];
int vis2[1500][1500];
int vis[1500][1500];
int kas[1500];
int dis[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
int ans=0;
  int n;
struct Node
{
    int x;
    int y;
    Node(int xx,int yy)
    {
        x=xx;
        y=yy;
    }
};
void bfs(int x,int y)
{
    ans++;
    int nx,ny;
    queue<Node>Q;
    Q.push(Node(x,y));
    Node top(0,0);
    while(!Q.empty())
    {

        top=Q.front();
       // cout<<top.x<<"  "<<top.y<<endl;
        Q.pop();
        vis[top.x][top.y]=ans;//这个#属于第ans个岛
        for(int i=0; i<4; i++)
        {
            nx=top.x+dis[i][0];
            ny=top.y+dis[i][1];
            if(nx>0&&nx<=n&&ny>0&&ny<=n&&!vis[nx][ny]&&ma[nx][ny]=='#')
            {
                Q.push(Node(nx,ny));
            }
            if(nx>0&&nx<=n&&ny>0&&ny<=n&&ma[nx][ny]=='.')
            {
                vis2[top.x][top.y]=1;//这个#周围有‘.'
            }

        }
    }
    return;
}
int main()
{

    cin>>n;
    memset(vis,0,sizeof(vis));
     memset(kas,0,sizeof(kas));
    memset(vis2,0,sizeof(vis2));
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            cin>>ma[i][j];
        }
    }

    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(ma[i][j]=='#'&&vis[i][j]==0)
            {
                bfs(i,j);
            }
        }
    }
    for(int i=1; i<=n; i++)//将和.相邻的#变成.,但是会影响不和.相邻的#,所以先变成$
    {
        for(int j=1; j<=n; j++)
        {
            if(ma[i][j]=='#'&&vis2[i][j])
            {
                ma[i][j]='$';
            }
        }
    }
    for(int i=1; i<=n; i++)//将$变成.
    {
        for(int j=1; j<=n; j++)
        {
            if(ma[i][j]=='$')
            {
                ma[i][j]='.';
            }
        }
    }
    int flag=0;
      for(int i=1; i<=n; i++)//统计剩下的岛(vis数组中有几个不同的值)
    {
        for(int j=1; j<=n; j++)
        {
            if(vis[i][j]>0&&kas[vis[i][j]]==0&&ma[i][j]=='#')
            {
                flag++;
                kas[vis[i][j]]=1;
            }
        }
    }
    cout<<ans-flag<<endl;
    return 0;
}
/*
9
.........
.#######.
.###.###.
.###.###.
.........
.........
.........
..##.....
.........
*/

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值