(bfs/bfs)连通块+最短路径

读入大量字符:快读配置

将cin,cout和scanf和printf解除绑定,提高效率。之后只能用cin,cout

std::ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

在输入是很多字符时,需要吃掉换行符

cin>>N;
    char next;
    cin.get(next);
    while(next!='\n')
        cin.get(next);

例如在读入一个N*N的地图时:

//读入地图
    for(int i=0; i<N; i++)
    {
   
        for(int j=0; j<N; j++)
        {
   
            cin.get(ch[i][j]);
        }
        //读完一行需要将行尾的换行符吃掉
        cin.get(next);
        while(next!='\n')
            cin.get(next);
    }

宽搜:队列和自定义结构体

结构体:

struct point //存储一个格子的横纵坐标
{
   
    int x,y;
};

宽搜模板:

void bfs(int i,int j)
{
   
    mark[i][j]=1;//标记为已经访问
    queue<point> q;//queue一般用自定义的类型
    q.push({
   i,j});//将当前格子封装到point里面并且插入队列
    int jing=0,lingshuijing=0;//记录当前所给地图中的#以及和.相邻的#
    while(!q.empty()) //一个while走完就是一个连通块走完了
    {
   
        point first=q.front();
        q.pop();
        jing++;
        bool beiyan=0;
        for(int k=0; k<4; k++)
        {
   
            int x=first.x+dx[k];
            int y=first.y+dy[k];
            if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='.')
            {
   
                beiyan=true;
            }
            //周边的#如果未被访问,则加入队列中
            if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='#'&&mark[x][y]==0)
            {
   
                q.push({
   x,y});
                mark[x][y]=1;
            }
        }
        if(beiyan)
        {
   
            lingshuijing++;
        }
    }
    if(jing==lingshuijing)
    {
   
        res++;
    }
}

例题:蓝桥杯2018全球变暖

  1. 完整题目:
    你有一张某海域 N×NN×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:


.##…
.##…
…##.
…####.
…###.

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

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。

具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

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





…#…


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

输入格式
第一行包含一个整数N。

以下 NN 行 NN 列,包含一个由字符”#”和”.”构成的 N×NN×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。

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

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

数据范围
1≤N≤10001≤N≤1000

输入样例1:
7

.##…
.##…
…##.
…####.
…###.

输出样例1:
1
2. 思路:
首先需要找到地图中岛屿在哪——使用bfs进行搜索,连通块问题。
然后对找到的岛屿的每一块陆地判断他周围是否有海,只要四周有一块海,那么这块陆地就是要被淹没的陆地。
被淹没的岛就是其中的每一块陆地都和海相邻,所以对第二步中和海相邻的陆地进行计数,如果等于连通块中的一块的全部陆地,那么这个岛屿会被淹没。

4. 代码:

#include<bits/stdc++.h>
using namespace std;
char ch[100][100];
char mark[1000][1000]= {
   0};
int N,res;
int dx[]= {
   0,0,1,-1};
int dy[]= {
   1,-1,0,0};

struct point //存储一个格子的横纵坐标
{
   
    int x,y;
};
void bfs(int i,int j)
{
   
    mark[i][j]=1;//标记为已经访问
    queue<point> q;//queue一般用自定义的类型
    q.push({
   i,j});//将当前格子封装到point里面并且插入队列
    int jing=0,lingshuijing=0;//记录当前所给地图中的#以及和.相邻的#
    while(!q.empty()) //一个while走完就是一个连通块走完了
    {
   
        point first=q.front();
        q.pop();
        jing++;
        bool beiyan=0;
        for(int k=0; k<4; k++)
        {
   
            int x=first.x+dx[k];
            int y=first.y+dy[k];
            if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='.')
            {
   
                beiyan=true;
            }
            //周边的#如果未被访问,则加入队列中
            if(x>=0&&x<N&&y>=0&&a
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值