lanqiao OJ 3513 岛屿个数(2023省赛)

简介: lanqiao OJ 3513 岛屿个数(2023省赛)

原题链接:3.岛屿个数 - 蓝桥云课 (lanqiao.cn)

感觉这个题出的真的特别好,考察了对bfs的使用,包括连通性的一系列判断,如果对bfs掌握的不熟练真的很难想出如何下手来做这道题。

这里我们需要用海水来进行bfs,海水可以渗透,也就是说可以走8个方向,因为我们要从任意一个边界点出发,所以我们需要把图扩展一下,变成n+2,m+2的图,我们把第0行第0列,和n+1行,n+1列变成0,也就是海水,这样的话我们从0,0开始遍历,就可以从每一个边界点进入判断,当然,我们的越界条件也要变成 n+2 , 和 m+2(这里真的很重要www , 博主刚开始做这道题,因为没有判别好边界问题导致直接全wa,要是这是在考场上这样,不得直接寄了,本来就不会几道),然后当我们第一次搜到一个岛屿的时候,他的初始状态是1,也就是说我们还没有搜索到过这个岛屿,这样的话我们就把最终答案 ans ++ ,然后对这个岛屿进行染色,染色当然很简单,就是一个判定连通性的问题,把这个1联通的所有1都变成2 ,这样就表示我们已经搜过这个岛屿了,如果这个岛屿内部也有岛屿,而且外面这个岛屿是封闭的我们的外界海水就渗透不进去,那我们就不会搜索到子岛屿,子岛屿也就不会参与计数;

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
 
using namespace std ;
const int N = 100 ;
int d1[4][2] = {{0,1},{0,-1},{1,0},{-1,0}} ;
int d2[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,1},{1,-1},{-1,-1}} ;
struct node{//这是我们记录搜索到的点的坐标
  int x , y;
  node(int xx ,int yy){
    x = xx , y = yy ;
  }
  bool operator < (const node & o) const {
    if(x == o.x) return y < o.y ;
    else return x < o.x ;
  }
};
queue<node> q ;//用于bfs
char mp[N][N] ;//存图
int n , m ;
int ans ;//返回值
void dfs(int x, int y){//染色,判断岛屿的上下左右四个方向,如果有陆地的话,索命他们是联通的,就对他们进行染色
  mp[x][y] = '2' ;
  for(int i = 0 ; i < 4 ; i ++){
    int tx = x + d1[i][0] , ty = y + d1[i][1] ;
    if(mp[tx][ty] == '1'){
      dfs(tx,ty) ;
    }
    
  }
}
 
void bfs1(){
  q.push(node(0,0)) ;
  while(!q.empty()){
    node now = q.front() ;
    q.pop() ;
    int x = now.x , y = now.y ;
    for(int i = 0 ; i < 8 ; i ++){
      int tx = x + d2[i][0] , ty = y + d2[i][1] ;
      if(tx<0||tx>n+1||ty<0||ty>m+1||mp[tx][ty] == '2') continue ;//越界或者已经搜索过了
      if(mp[tx][ty] == '1'){
        ans ++ ; dfs(tx,ty) ;//如果碰到新的陆地就进行染色
      }
      if(mp[tx][ty] == '0'){//如果是海水,就进入队列让下一个海水继续渗透
        mp[tx][ty] = '2' ; 
        q.push(node(tx,ty)) ;
      }
    }
  } 
}
 
int main(){
  int t ; cin >> t ;
  while(t --){
    ans = 0 ;
    memset(mp,'0',sizeof(mp));
    cin >> n >> m ;
    for(int i = 0 ; i <= n ; i++) mp[i][0] = '0' ;//对边界进行初始化,保证从所有边界点的海水进行渗透
    for(int j = 0 ; j <= m ; j++) mp[0][j] = '0' ;
    for(int i = 1 ; i <= n ; i ++){
      for(int j = 1 ; j <= m ; j ++){
        cin >> mp[i][j] ;
      }
    }
    bfs1() ;
    cout << ans << endl ;
  }
  
}
目录
相关文章
|
数据安全/隐私保护
使用加密工具类进行有效的字符串加密——CSDN博客
使用加密工具类进行有效的字符串加密——CSDN博客
|
12月前
lanqiao OJ 230 调手表
lanqiao OJ 230 调手表
86 1
|
12月前
lanqiao OJ 108 发现环
lanqiao OJ 108 发现环
59 1
|
12月前
lanqiao OJ 261 九宫重排
lanqiao OJ 261 九宫重排
48 0
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
181 3
|
网络协议 Linux 网络架构
默认网关详解:网络通信的无声守护者
【4月更文挑战第22天】
4988 3
|
12月前
lanqiaoOJ 563 采药
lanqiaoOJ 563 采药
64 6
|
12月前
lanqiao oj 奇怪的段
lanqiao oj 奇怪的段
43 0
|
C++ 容器
【C++STL基础入门】list交换、翻转,排序、合并和拼接操作
【C++STL基础入门】list交换、翻转,排序、合并和拼接操作
1139 0
|
SQL 分布式计算 大数据
大数据=SQL Boy,SQL Debug打破SQL Boy 的僵局
大数据=SQL Boy,SQL Debug打破SQL Boy 的僵局
242 0