当前位置: 代码迷 >> 综合 >> 51NOD 1276 岛屿的数量(脑洞+思维)
  详细解决方案

51NOD 1276 岛屿的数量(脑洞+思维)

热度:88   发布时间:2023-12-06 19:42:35.0

传送门 

有N个岛连在一起形成了一个大的岛屿,如果海平面上升超过某些岛的高度时,则这个岛会被淹没。原本的大岛屿则会分为多个小岛屿,如果海平面一直上升,则所有岛都会被淹没在水下。
给出N个岛的高度。然后有Q个查询,每个查询给出一个海平面的高度H,问当海平面高度达到H时,海上共有多少个岛屿。例如:
岛屿的高度为:{2, 1, 3, 2, 3}, 查询为:{0, 1, 3, 2}。
当海面高度为0时,所有的岛形成了1个岛屿。
当海面高度为1时,岛1会被淹没,总共有2个岛屿{2} {3, 2, 3}。
当海面高度为3时,所有岛都会被淹没,总共0个岛屿。
当海面高度为2时,岛0, 1, 3会被淹没,总共有2个岛屿{3} {3}。
Input
第1行:2个数N, Q中间用空格分隔,其中N为岛的数量,Q为查询的数量(1 <= N, Q <= 50000)。
第2 - N + 1行,每行1个数,对应N个岛屿的高度(1 <= A[i] <= 10^9)。
第N + 2 - N + Q + 1行,每行一个数,对应查询的海平面高度(1 <= Q[i] <= 10^9)。
Output
输出共Q行,对应每个查询的岛屿数量。
Input示例
5 4
2
1
3
2
3
0
1
3
2
Output示例
1
2
0
2


分析:

水没到山谷的时候,岛屿+1,山峰的时候-1,否则不变。其实就是这个道理,那么我们现在用一个标记数组将所有淹没过的岛屿标记一下,那么在根据上述的分析 就可以写了,但是这样的话 很容易超时,所以我们先将所有的岛屿和要查询的岛屿从小到大排序,在排序之前要记得保留下标,然后判断就行了。这是一个锻炼脑洞的题目。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50005;
struct Node
{int val, id;
}a[maxn], b[maxn];
bool vis[maxn];
int ans[maxn];
bool cmp(Node p, Node q)
{return p.val < q.val;
}
int main()
{int n, q;while(scanf("%d%d", &n, &q) != EOF){memset(vis, false, sizeof(vis));for(int i = 0; i < n; i++){scanf("%d", &a[i].val);a[i].id = i;}for(int i = 0; i < q; i++){scanf("%d", &b[i].val);b[i].id = i;}sort(a, a+n, cmp);sort(b, b+n, cmp);int sum = 1, i = 0, j = 0;while(i < q){while(a[j].val <= b[i].val && j < n){if(a[j].id == 0)//判断是不是第一个点{if(vis[1])sum--;}else if(a[j].id == n-1)//判断是不是最后一个点{if(vis[n-2])sum--;}else//中间的点{if(!vis[a[j].id-1] && !vis[a[j].id+1])///山谷sum++;else if(vis[a[j].id-1] && vis[a[j].id+1])///山峰sum--;}vis[a[j].id] = true;///标记被淹没j++;}ans[b[i].id] = sum;i++;}for(int i = 0; i < q; i++)printf("%d\n", ans[i]);}return 0;
}