寒假每日一题(1.6)解析

该题是说我们有一堆相邻的小山,在暴风雨来临期间水平面会上涨慢慢逐步淹没小山,然后未被淹没相邻的地方所连接的就是岛屿,最后求在水平面上涨过程当中某一时刻所能够看到的最大的岛屿数量。

那么我们只需要考虑所出现的高度即可,未出现的高度是不会影响小山是否淹没的情况,一共有10^{5}个高度,因此可以枚举我们的高度,假设在枚举时的高度与键盘所输入的小山高度重合了,那么我们就认为小山被覆盖了。在枚举完之后,随着水平面上涨,我们只需关注变化的小山即可,就是说在水平面未到达前没有被淹没到达后被淹没的小山,那么此时该小山共有四种情况:

1.左边小山比当前小山高右边小山比当前小山低、2.右边小山都比当前小山高左边小山比当前小山低、3.左右两边小山都比当前小山低、4.左右两边小山都比当前小山高。

那么前两种情况对于岛的数量是没有影响的,第三种情况会使原来岛的数量-1,第四种情况会使原来岛的数量+1。,最后我们还需考虑相等的山的特殊情况,此时我们只需把相等的山看作一个山,即在初始时候通过筛选把相等的山删除掉即可。

下面给出相应代码参考:

c++代码:

#include <iostream>
#include <algorithm>
using namespace std;

#define height first
#define pos second
const int N = 1e5 + 10;

int n;
typedef pair<int, int> PII;
PII a[N];   // 存放 n 个田地的 位置 和 高度 
bool vis[N];    // 存储 n 个田地是否被淹没的状态:0表示没被淹没  1表示被淹没 

int main()
{
    // 1. 将 n 个田地的 顺序 和 高度 读入 a 数组中去 
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        int h;
        cin >> h;
        a[i].pos    = i;
        a[i].height = h;
    }
    // 2. 按照高度排序:低洼的在前面 
    sort(a, a + n);

    int ans = 1, cnt = 1;
    for(int i = 0; i < n; i++)
    {
        // 将当前位于 cur 处的田地淹没
        int cur = a[i].pos;
        vis[cur] = 1;
        // 判断 cur 两边的淹没状态:未被淹没的状态 -> true 
        bool le = ((cur - 1 >= 0) && !vis[cur - 1]);
        bool ri = ((cur + 1 <  n) && !vis[cur + 1]);
        if(le && ri) cnt ++;    // 都没被淹没 
        else if(!le && !ri) cnt --; // 都被淹没
        // 判断是否需要更新 ans : 之所以需要判断是因为防止出现连续几个相同高度的田地 
        if(i == n - 1 || a[i].height != a[i+1].height)
            ans = max(ans, cnt); 
    }

    cout << ans << endl;

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值