Islands HDU - 2808

题目链接:Islands HDU - 2808

===================================================

Islands

Time Limit: 1000 ms
Memory Limit: 32768 kB

Description

There are so many islands in the sea. Some islands are enclosed by other ones. So, we can classify all the islands to several levels. An island has a level of 0 if it is contains no other islands. An island has a level of K+1 if it contains one or more islands and the highest level of the contained island(s) is K. Now, the map of the sea is given. Your task is to calculate the areas of islands in each level.

Input

The input contains several test cases. Each test case starts with a line contains two numbers N and M(1<=N<=100,1<=M<=100) which indicate the size of the map. The next N lines will contain M characters each to represent the map. Each character is either ‘x’ or ‘.’. A sea is defined as a maximal connected group of ‘.’ cells, where two ‘.’ cells are connected if they are vertically or horizontally adjacent. An island is defined as a maximal connected group of ‘x’ cells, where two ‘x’ cells are connected if they are vertically, horizontally, or diagonally adjacent. An island A contains island B if A and B are different and if you start sailing from any point of island B, you won’t be able to sail out of island A.

Output

For each test case, output a single line with K+1 integers, where K is the highest level of an island in the map. The i-th number in the line is the total area of islands of level (i-1).

Sample Input

1 1
x
5 7
.xxxxx.
x…x
x.x.x.x
x…x
.xxxxx.

Sample Output

1
2 16

===================================================

题意:就是100*100的地图,上面有海和岛,岛是8各方向判断是否连接的,然后如果一座岛里面没有其他岛的话,他的岛等级就是0,如果存在其他岛的话,他的等级就是他的子岛最大等级+1.

算法:DFS

思路:

  • 这题和前面那道埃及文字题目差不多,Ancient Messages HDU - 3839
  • 就是从边缘开始判断,海的话就进行dfs判断,把所有外海标记了,然后与外海邻接的岛就记录;然后在从这些岛开始dfs判断,一座岛一座岛标记,然后每次都把与这些岛邻接的内海进行记录,再对这些内海进行标记,反正就是互相套娃。
  • 当一座岛里面没有海或者内海里面没有外岛,他的等级就是0了。

易错点:注意细节,耐心耐心耐心

===================================================

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <map>

using namespace std;

const int INF = 0x3f3f3f3f;

char ditu[100][100];
bool vis[100][100];
bool visB[100][100];
bool visW[100][100];
int n,m;
int xx[]={1,-1,0,0,-1,-1,1,1};
int yy[]={0,0,1,-1,-1,1,1,-1};
int ans[100],ansN;

void show(){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++) cout<<ditu[i][j];cout<<endl;
    }cout<<endl;
}

void init(){
    for(int i=0;i<n;i++) cin>>ditu[i];
    memset(vis,false,sizeof vis);
    memset(visB,false,sizeof visB);
    memset(visW,false,sizeof visW);
    memset(ans,0,sizeof ans);
    ansN = -1;
}

struct node{
    int x,y;
    node(int a,int b):x(a),y(b) {};
};

void show2(vector<node> a){
    cout<<"vector: ";
    for(int i=0;i<a.size();i++){
        cout<<a[i].x<<" "<<a[i].y<<" | ";
    }cout<<endl;
}

void show3(){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++) cout<<vis[i][j]<<" ";cout<<endl;
    }cout<<endl;
}

void  cleanW(int a,int b,vector<node> &v){
    vis[a][b]=true;
    for(int i=0;i<4;i++){
        int x = a + xx[i] , y = b+ yy[i];
        if(x<0||x>=n||y<0||y>=m||vis[x][y]) continue;
        if(ditu[x][y]=='.') cleanW(x,y,v);
        else if(!visB[x][y]) visB[x][y] = true,v.push_back(node(x,y));
    }
}

void  cleanB(int a,int b,vector<node> &v,int &c){
    vis[a][b]=true;c++;
    for(int i=0;i<8;i++){
        int x = a + xx[i] , y = b+ yy[i];
        if(x<0||x>=n||y<0||y>=m||vis[x][y]) continue;
        if(ditu[x][y]=='x') cleanB(x,y,v,c);
        else if(!visW[x][y]) visW[x][y] = true,v.push_back(node(x,y));
    }
}

int dfs(int x,int y) {
    vector<node> v,v2;
    int res = 0;
    int level = 0;
    cleanB(x,y,v,res);
    if(v.size()==0) {ans[0]+=res;return 0;}
    //show2(v);show3();
    for(int i=0;i<v.size();i++){
        int a = v[i].x , b = v[i].y;
        if(vis[a][b]) continue;
        cleanW(a,b,v2);
    }
   // show2(v2);show3();
    if(v2.size()==0) {ans[0]+=res;return 0;}
    for(int i=0;i<v2.size();i++){
        int a = v2[i].x , b = v2[i].y;
        if(vis[a][b]) continue;
        level  = max(level,dfs(a,b)+1);
    }
    ans[level]+=res;
    return level;
};

void solve(){
    vector<node> v;
    for(int i=0;i<n;i++){
        if(!vis[i][0]){
            if(ditu[i][0]=='.') cleanW(i,0,v);
            else if(!visB[i][0]) visB[i][0] = true,v.push_back(node(i,0));
        }
        if(!vis[i][m-1]){
            if(ditu[i][m-1]=='.') cleanW(i,m-1,v);
            else if(!visB[i][m-1]) visB[i][m-1] = true,v.push_back(node(i,m-1));
        }
    }
    for(int j=1;j<m-1;j++){
        if(!vis[0][j]){
            if(ditu[0][j]=='.') cleanW(0,j,v);
            else if(!visB[0][j]) visB[0][j] = true,v.push_back(node(0,j));
        }
        if(!vis[n-1][j]){
            if(ditu[n-1][j]=='.') cleanW(n-1,j,v);
            else if(!visB[n-1][j]) visB[n-1][j] = true,v.push_back(node(n-1,j));
        }
    }
//------------------------------------------------------------------------------------
    //show2(v);show3();
    for(int i=0;i<v.size();i++){
        int a = v[i].x , b = v[i].y;
        if(vis[a][b]) continue;
        ansN  = max(ansN,dfs(a,b));
    }
}

int main()
{
    while(cin>>n>>m){
        init();//show();
        solve();
        //cout<<ansN<<endl;
        if(ansN==-1) {cout<<endl;continue;}
        for(int i=0;i<ansN;i++) cout<<ans[i]<<" ";cout<<ans[ansN]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盐太郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值