ACW4007.非零段划分
思路
- 模拟海水退潮的过程
- 每遇到一个波峰,如果海水恰好在波峰的位置,那么岛屿的数量会增加1
- 每遇到一个波谷,如果海水恰好在波谷的位置,那么岛屿的数量会减少1
- 逐个遍历数组,记录海水在相应位置的变化(有可能多个波峰高度一致)
- 模拟退潮过程,变化过程中一定会实现最大岛屿数量。
此题的关键在于掌握两点:
如何记录波峰波谷的数量(前后分别加上0),三个一组,从后往前扫(注意边界留空)
nums[0] = nums[n + 1] = 0;
n = unique(nums, nums + n + 2) - nums;
for (int i = 1; i < n; ++i) {
if (nums[i - 1] < nums[i] && nums[i] > nums[i + 1]) {
cnt[nums[i]] += 1;
} else if (nums[i - 1] > nums[i] && nums[i] < nums[i + 1]) {
cnt[nums[i]] -= 1;
}
}
如何进行去除相邻重复项(
unique
和手动unique
的方法都需要了解)(手动unique
就是store_index
指针)// cnt[i]表示水位如果在nums[i]高度,减少和增加的岛的数量
n = unique(nums, nums + n + 2) - nums;
代码
```cpp
include
include
include
using namespace std;
const int N = 5e5 + 5; const int M = 1e5 + 5;
int main() { int n = 0; scanf(“%d”, &n); int nums[N], cnt[N]; memset(cnt, 0, sizeof(cnt)); for (int i = 1; i <= n; i++) { scanf(“%d”, &nums[i]); }
nums[0] = nums[n + 1] = 0;
// cnt[i]表示水位如果在nums[i]高度,减少和增加的岛的数量
n = unique(nums, nums + n + 2) - nums;
for (int i = 1; i < n; ++i) {
if (nums[i - 1] < nums[i] && nums[i] > nums[i + 1]) {
cnt[nums[i]] += 1;
} else if (nums[i - 1] > nums[i] && nums[i] < nums[i + 1]) {
cnt[nums[i]] -= 1;
}
}
// 逐个遍历,从高处往下降,模拟岛屿露出水面的过程
int ans = 0, summ = 0;
for (int i = M; i > 0; i--) {
summ += cnt[i];
ans = max(ans, summ);
}
printf("%d\n", ans);
return 0;
} ```