该题是说我们有一堆相邻的小山,在暴风雨来临期间水平面会上涨慢慢逐步淹没小山,然后未被淹没相邻的地方所连接的就是岛屿,最后求在水平面上涨过程当中某一时刻所能够看到的最大的岛屿数量。
那么我们只需要考虑所出现的高度即可,未出现的高度是不会影响小山是否淹没的情况,一共有个高度,因此可以枚举我们的高度,假设在枚举时的高度与键盘所输入的小山高度重合了,那么我们就认为小山被覆盖了。在枚举完之后,随着水平面上涨,我们只需关注变化的小山即可,就是说在水平面未到达前没有被淹没到达后被淹没的小山,那么此时该小山共有四种情况:
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;
}