题目:全球变暖(蓝桥OJ 0178)

问题描述:

 


解题思路:

        首先,我们需要注意,当一个岛屿被淹没分成两个甚至更多岛屿的情况,这种情况下被淹没的岛屿本质上只是淹没一个。因此我们不能直接用原来的岛屿数减淹没后的小岛个数。 

        所以我们需要给原本的岛屿做上颜色标记,则淹没后剩余的颜色总数就是被淹的小岛数。再用原来的岛屿数减剩余的颜色总数就是答案

        具体步骤:1.染色(dfs)2.计算颜色数 3.ans 


题解:

#include<bits/stdc++.h>
using namespace std;
const int N = 1005;

char mp[N][N];  // 选择字符类型数组 
int n, scc, col[N][N];  // scc:颜色 col[][]:颜色数组,内部放位置的颜色

// 四个方向 
int dy[] = {0, 0, 1, -1};
int dx[] = {1, -1, 0, 0};

bool vis[N * N];  // 颜色标记数组

// 染色dfs
void dfs(int x, int y){

  col[x][y] = scc;
  for(int i = 0; i < 4; i++){  // 四个方向染色
    int nx = x + dx[i], ny = y + dy[i];
    if(mp[nx][ny] == '.' || col[nx][ny])continue;  // 因为边界就是海说以不需要具体的边界限      
    制。当该点是海或是有颜色就下一步
    dfs(nx, ny);
  }
}

int main()
{
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  
  cin >> n;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= n; j++)cin >> mp[i][j];
  }


  // 染色:当该点是空白岛屿时对该点做dfs以染色整个岛
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= n; j++){
      if(mp[i][j] == '.' || col[i][j])continue;
      scc++;
      dfs(i, j);
    }
  }


  // 计算淹没后剩余颜色:不用做淹没后图,直接在每个四个方向都是岛的点计算颜色数(因为他们肯定不会被淹没)。当找到一个没被标记的颜色就标记他
  int ans = 0;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= n; j++){

      if(mp[i][j] == '.')continue;

      bool tag = true;
      for(int k = 0; k < 4; k++){
        int x = i + dx[k], y = j + dy[k];
        if(mp[x][y] == '.')tag = false;// 判断上下左右是不是岛,是就返回ture
      }

      if(tag){  // 上下左右是岛的情况下再判断有没有被标记
        if(!vis[col[i][j]])ans++;
        vis[col[i][j]] = true;
      }

    }
  }
  cout << scc - ans << '\n';  // 颜色总数(总岛屿数) - 剩余岛屿数 = 淹没数 
  return 0;
}

知识点:dfs

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值