6.建造最大岛屿

给定一个由 1(陆地)和 0(水)组成的矩阵,你最多可以将矩阵中的一格水变为一块陆地,在执行了此操作之后,矩阵中最大的岛屿面积是多少。

岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿是被水包围,并且通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。之后 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示最大的岛屿面积。

 

#include<algorithm>
#include<iostream>
const int N =60;
/// @brief 
int n,m;
using namespace std;
#include<vector>

#include <unordered_map>
#include <unordered_set>
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//定义方向向量
int ans;
void dfs(int x,int y,int mark,vector<vector<int>>&g,vector<vector<bool>>&vis){
    if(vis[x][y]||g[x][y]==0){
        return;
    }
        vis[x][y]=true;//标记访问了,然后从这个点开始往四周搜索
        g[x][y]=mark;//打上标签,代表是编号为mark的土地
      ans++;//面积+1,编号为mark的面积+1
        for(int i=0;i<4;i++){
            int nx=x+dir[i][0];
            int ny=y+dir[i][1];
            if(nx<0||ny<0||nx>n-1||ny>m-1)  continue;//越界了,就跳过这个点

            
                dfs(nx,ny,mark,g,vis);
            
        }
       
}
int main(){
    cin>>n>>m;
    vector<vector<int>>g(n,vector<int>(m,0));//创建一个图,把数据存进去
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    cin>>g[i][j];
    bool isall=true;//是否全是陆地,如果是,那么直接输出n*m就好了
    int mark=2;//编号从2开始,因为1代表了陆地
    vector<vector<bool>>vis(n,vector<bool>(m,false));//用来标记是否访问过
    unordered_map<int ,int> gridNum;//表示编号为i的土地面积是2;

    unordered_set<int> gv;//是否已经用过这片土地了
    //第一步,先把各个分割的陆地面积求出来;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(g[i][j]==0)  //只要出现了一个海就说明不是全大陆
                isall=false;//不是全大陆
                if(!vis[i][j]&&g[i][j]==1){
                    //1
                    ans=0;
                    dfs(i,j,mark,g,vis);

                    //扫完之后,ans就可以存储了
                    gridNum[mark]=ans;//编号为mark的面积是ans;
                    mark++;//每次遍历完都意味着一块区域的搜索完成,因此需要加加编号
                }
               
            }
        }
         
         if(isall){
            printf("%d",n*m);
            return 0;
         }
           int result=0;
    for(int i=0;i<n;i++){

        for(int j=0;j<m;j++){
                int count=1;//将一块海洋变为陆地,所以最少都有1
                gv.clear();//每次要重置,因为对于任何一个海洋来说,他对于各个编号的陆地影响是不同的
                if(g[i][j]==0){//找到一个海洋,试图把它变为陆地看看,对于其他土地的影响
                     
                     for(int k=0;k<4;k++){
                         int nx=i+dir[k][0];
                         int ny=j+dir[k][1];
                         if(nx<0||ny<0||nx>n-1||ny>m-1){
                            continue;//越界跳过
                         }
                         if(gv.count(g[nx][ny])){
                            continue;
                         }
                         gv.insert(g[nx][ny]);//这个编号岛屿已经影响过了
                         count+=gridNum[g[nx][ny]];
                      
                     }

                }
                  result=max(result,count);
        }
    }
   
          cout<<result<<endl;
    return 0;
}

思路写的很详细了,大概就是,先把每个独立区域的陆地面积算出来

之后枚举每一个海洋,看看他会对每个板块造成怎样的影响,把面积都存起来,取最大值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值