计蒜客题解——T1769:最大岛屿

题目相关

题目链接

计蒜客,https://nanti.jisuanke.com/t/T1405

我的OJ,http://47.110.135.197/problem.php?id=5254

题目描述

神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等。加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠 1 号要征服各个海岛的海盜,最后成为海盗王。

这是一个由海洋、岛屿和海盗组成的危险世界。面对危险重重的海洋与诡谲的对手,如何凭借智慧与运气,建立起一个强大的海盗帝国。

杰克船长手头有一张整个海域的海图,上面密密麻麻分布着各个海屿的位置及面积。他想尽快知道整个海域共有多少岛屿以及最大岛屿的面积。

输入格式

第 11 行:M,N,T,表示海域的长,宽及一个单位表示的面积大小

接下来有 M 行 ,每行有 N 个 01 组成的序列以及其中穿插一些空格。0 表示海水,1 表示陆地,其中的空格没用,可以忽略掉。

输出格式

输出一行,有 2 个整数,一个空格间隔,表示整个海域的岛屿数,以及最大岛屿的面积。

输入样例

8 16 99
00000000 00000000
0000110011000000
0001111000111000
0000000  00 0000000
00111  111000001  10
001110000  0000000
0100001111 111100
0000000000000000

输出样例

5 990

数据范围

1 ≤ N, M, T ≤500。

说明

1:若一个陆地八个方向之一(上、下、左、右、左上、右上、左下、右下)的位置也是陆地,则视为同一个岛屿。

2:假设第一行,最后一行,第一列,最后一列全为 0。

题目分析

题意分析

在区域内找出由 1 构成的岛屿的数量,并计算最大岛屿的面积。

因此根据题意,我们可以知道,这是一题标准的 BFS 题目。当然本题可以使用 DFS,但是最好的方法是 BFS,因为 DFS 递归深度过深会导致程序爆堆栈。

特别说明

1、本题在路径搜索的时候是 8 个方向的,即上、下、左、右、左上、右上、左下、右下。

2、输入数据之间可能有空格,要忽略这个空格。

样例数据分析

和其他模板题差不多,没有特别需要注意的。下面我们使用下图做一个简单说明:

从上图,我们可以清楚的看到,一共 5 个岛屿,最大的岛屿由 10 个 1 组成,根据题目意思,每个 1 表示面积为 99,所以最大岛屿面积为 990。

算法思路

1、读入数据,处理空格。

2、将所有为 1 的位置加入到 vector 中。

3、以 vector 中所有坐标为起点,进行 BFS,每次搜索记录面积,搜索完记录岛屿数量。

4、输出。

AC 参考代码

BFS 代码

#include <iostream>
#include <queue>
#include <vector>
 
using namespace std;
 
const int MAXN = 500+4;
const int MAXM = 500+4;
 
typedef struct _POS {
    int x;
    int y;
} POS;
 
typedef struct _ROOM {
    int n;
    int m;
    char data[MAXN][MAXM];
    bool vis[MAXN][MAXM];
} ROOM;
 
vector<POS> myvect;
 
int bfs(ROOM &room, const POS &pos) {
    queue<POS> q;
    q.push(pos);
    room.vis[pos.x][pos.y]=true;
 
    const POS moves[] = {{0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}};
    POS cur;
    POS next;
    int steps = 0;
 
    while (false==q.empty()) {
        steps++;
        cur = q.front();
        q.pop();
 
        for (int i=0; i<8; i++) {
            next.x = cur.x+moves[i].x;
            next.y = cur.y+moves[i].y;
 
            if (next.x>=0&&next.x<room.n
                &&next.y>=0&&next.y<room.m
                &&'1'==room.data[next.x][next.y]
                &&false==room.vis[next.x][next.y]) {
                room.vis[next.x][next.y]=true;
                q.push(next);
            }
        }
    }
    return steps;
}
 
int main() {
    int t;
    ROOM room = {};
    cin>>room.n>>room.m>>t;
 
    char data;
    for (int i=0; i<room.n; i++) {
        for (int j=0; j<room.m; ) {
            cin>>room.data[i][j];
            if (' '!=room.data[i][j])  {
                if ('1'==room.data[i][j]) {
                    POS pos = {i,j};
                    myvect.push_back(pos);
                }
                j++;
            }
        }
    }
 
    int nums=0;
    int area=0;
    vector<POS>::iterator it;
    for (it=myvect.begin(); it<myvect.end(); it++) {
        POS pos = *it;
        if (false==room.vis[pos.x][pos.y]) {
            area = max(area, bfs(room, pos));
            nums++;
        }
    }
 
    cout<<nums<<" " << area*t <<endl;
 
    return 0;
}

DFS 代码

#include <iostream>
#include <queue>
#include <vector>
 
using namespace std;
 
const int MAXN = 500+4;
const int MAXM = 500+4;
 
typedef struct _POS {
    int x;
    int y;
} POS;
 
typedef struct _ROOM {
    int n;
    int m;
    char data[MAXN][MAXM];
    bool vis[MAXN][MAXM];
} ROOM;
 
vector<POS> myvect; 

int steps;

int dfs(ROOM &room, const POS &pos) {
    const POS moves[] = {{0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}};
    POS next;

    for (int i=0; i<8; i++) {
        next.x = pos.x+moves[i].x;
        next.y = pos.y+moves[i].y;

        if (next.x>=0&&next.x<room.n
            &&next.y>=0&&next.y<room.m
            &&'1'==room.data[next.x][next.y]
            &&false==room.vis[next.x][next.y]) {
            room.vis[next.x][next.y]=true;
            steps++;
            dfs(room, next);
        }
    }
}
 
int main() {
    int t;
    ROOM room = {};
    cin>>room.n>>room.m>>t;
 
    char data;
    for (int i=0; i<room.n; i++) {
        for (int j=0; j<room.m; ) {
            cin>>room.data[i][j];
            if (' '!=room.data[i][j])  {
                if ('1'==room.data[i][j]) {
                    POS pos = {i,j};
                    myvect.push_back(pos);
                }
                j++;
            }
        }
    }
 
    int nums=0;
    int area=0;
    vector<POS>::iterator it;
    for (it=myvect.begin(); it<myvect.end(); it++) {
        POS pos = *it;
        if (false==room.vis[pos.x][pos.y]) {
            steps = 0;
            dfs(room, pos);
            area = max(area, steps);
            nums++;
        }
    }
 
    cout<<nums<<" " << area*t <<endl;
 
    return 0;
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力的老周

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

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

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

打赏作者

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

抵扣说明:

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

余额充值