AcWing 2014.岛 (离散化,枚举)
题目链接
https://www.acwing.com/problem/content/2016/
思路
题目意思是求淹没一定数量的田地,切割这些岛达到最大值。
一般会想到枚举,但是枚举显然时间复杂度过高,达到了O(n²),会超时。
优化思路:
将所有岛的高度排序,从最低的岛开始淹。
由于后续的的高度也是淹掉前面的低的岛,所以可以不用太管淹过的岛。
这样下来,有俩种特殊情况:
而其他情况则是不变。
这样的话,我们只需要去重即可,将一样高度的田地合起来当做同一个小山进行判断,即可避免很多问题。
AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int n;
int h[N];
pair <int, int>q[N];
int main(int argc, char* argv[])
{
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> h[i];
}
n = unique(h + 1, h + n + 1) - h - 1;//除去相邻部分同样高的田地
h[n + 1] = 0;
for(int i=1;i<=n;i++)
{
q[i] = { h[i],i };
}
sort(q + 1, q + n + 1);
int res = 1, cnt = 1;
//初始连在一起,只有一座山
for(int i=1;i<=n;i++)
{
int k = q[i].second;
if (h[k - 1] < h[k] && h[k + 1] < h[k])
cnt--;
else if (h[k - 1] > h[k] && h[k + 1] > h[k])
cnt++;
if (q[i].first != q[i + 1].first)
res = max(res, cnt);
}
cout << res;
}
心得
感觉题目没看懂,比较锻炼思维的题。