51Nod-1276-岛屿的数量
51Nod-1276- 岛屿的数量
有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, 因为query比较大量,先保存起来query。
2, 采用模拟法, 因为随着水位下降, 岛屿的出现是会发生变化的。 同时高度节点 和 query 查询高度, 进行排序, 同时进行水位降低模拟,
露出水面的高度也逐一出现, 如果 当前高度的左边和右边都是陆地,则岛屿数量-1, 若左边或者右边是陆地,而数量不变,若左边右边都不是陆地,
岛屿数量则+1, 可以知道每一个query 状态下的岛屿数量。
3, 时间复杂度: max( O(n*logn), O(q*logq), O(n + q) ) = O(n*logn)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int MAXN = 50000;
int n, q, cnt, ans[MAXN], vis[MAXN];
struct Node{
int h, p;
}nd[MAXN], query[MAXN];
int cmp(const void *a, const void *b){
Node *aa = (Node *)a;
Node *bb = (Node *)b;
return aa->h - bb->h;
}
void solver(){
memset(vis, 0, sizeof(vis));
cnt = 0;
int tmp, i = n-1, j=q-1;
while(i>=0 && j>=0){
if(query[j].h >= nd[i].h){
ans[query[j].p] = cnt;
j--;
}else{
tmp = nd[i].p;
if(tmp == 0){
if(vis[tmp+1] != 1){
cnt++;
}
}else if(tmp == n-1){
if(vis[tmp-1] != 1){
cnt++;
}
}else{
if(vis[tmp-1]==1 && vis[tmp+1]==1){
cnt--;
}else if(vis[tmp-1] == 0 && vis[tmp+1]==0){
cnt++;
}
}
vis[tmp] = 1;
i--;
}
}
while(j>=0){
ans[query[j].p] = cnt;
j--;
}
}
int main(){
freopen("in.txt", "r", stdin);
int val;
while(scanf("%d %d", &n, &q) != EOF){
for(int i=0; i<n; ++i){
scanf("%d", &val);
nd[i].h = val;
nd[i].p = i;
}
qsort(nd, n, sizeof(nd[0]), cmp);
for(int i=0; i<q; ++i){
scanf("%d", &val);
query[i].h = val;
query[i].p = i;
}
qsort(query, q, sizeof(query[0]), cmp);
solver();
for(int i=0; i<q; ++i){
printf("%d\n", ans[i]);
}
}
return 0;
}

浙公网安备 33010602011771号