首页 > 代码库 > 51nod 1276 1276 岛屿的数量 (很好玩的题目

51nod 1276 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 4213230132
Output示例
1202

 

这个题目用了一些小技巧 

可以看作1-n周围的已经被淹没 cnt = 2;

那么 cnt -1 就是答案

当一个岛被淹没 如果他的左右有一块被淹没的区域 那么cnt不变

当周围没被淹 那么cnt++

如果周围都被淹没 那么淹没的区域为cnt--

技术分享
#include<stdio.h>#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<climits>#include<vector> using namespace std;const int N = 5e4+10;int min_h = INT_MAX,max_h = INT_MIN;struct data{    int h,id;   /* data */}Q[N];bool vis[N];vector<int>v[N],num;int H[N];int ans[N];int getid(int x){    x++;    return lower_bound(num.begin(),num.end(),x)-num.begin()-1; }bool cmp(data a,data b){    return a.h<b.h;}int cnt = 2;void check(int pos){    vis[pos] = true;    if(vis[pos+1]&&vis[pos-1])    {        cnt--;    }    else{        if(vis[pos+1]||vis[pos-1])        {            ;        }        else{            cnt++;        }    }}int main(){    int n,q,t;    scanf("%d%d",&n,&q);    for(int i=1;i<=n;i++)    {        scanf("%d",&t);        num.push_back(t);        H[i] = t;        max_h = max(max_h,t);        min_h = min(min_h,t);    }    sort(num.begin(),num.end());    num.erase(unique(num.begin(),num.end()),num.end() );    for(int i=1;i<=n;i++)    {        //cout<<getid(H[i])<<endl;        v[getid(H[i])].push_back(i);    }    vis[0] = vis[n+1] = true;        for(int i=0;i<q;i++)    {        scanf("%d",&Q[i].h);        Q[i].id = i;    }    sort(Q,Q+q,cmp);    int pre = -1;    for(int i=0;i<q;i++)    {        if(Q[i].h>=max_h)        {            ans[Q[i].id] = 0;            continue;        }        if(Q[i].h<min_h)        {            ans[Q[i].id] = 1;            continue;        }        int now = getid(Q[i].h);        //cout<<endl<<"H: "<<Q[i].h<<" id:  "<<now<<endl;        for(int j = pre+1;j<=now;j++)        {            int len = v[j].size();            for(int k=0;k<len;k++)            {                check(v[j][k]);               //cout<<v[j][k]<<"  ";            }        }        pre = now;        ans[Q[i].id] = cnt - 1;    }    for(int i=0;i<q;i++)    {        printf("%d\n",ans[i]);    }    return 0;}
AC代码

 

51nod 1276 1276 岛屿的数量 (很好玩的题目