岛屿的数量 51Nod

来源:互联网 发布:Java 优化网站 编辑:程序博客网 时间:2024/04/30 06:16

有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 <= Aii <= 10^9)。 
第N + 2 - N + Q + 1行,每行一个数,对应查询的海平面高度(1 <= Qii <= 10^9)。
Output
输出共Q行,对应每个查询的岛屿数量。
Sample Input
5 4213230132
Sample Output
1202


思路:这个题做的我是一脸懵逼,开始的时候我用暴力,超时,后来又用结构体排序(我只用一个结构体)错误,很崩溃,最后上网查看大牛们的代码,才明白。(太考验思维,原谅我的智商)。

这个题需要用两个结构体,第一个存岛屿的高度,和岛屿的位置,后面用sortr按岛屿高度从小到大排序。第二个存查询高度,和查询的先后,再用sort按查询高度从小到大排序(这个大大减少的时间空间的复杂度)。如果按照这样排序,我们可以从小到大,查询一遍即可(已经查询过的就不需要在查了)(真的很难想到)。

在介绍岛屿怎么样是连成的,我们对这些岛进行处理的时候处理两种情况:第一种就是多了一片岛屿,第二种就是少了一片岛屿,对应第一种情况,如果当前去掉的这个岛屿的两边都是岛屿,那么才能多一片岛屿,对于第二种情况,如果当前去掉的这个岛屿的两边都是水了,我们才能少了一片岛屿。在结构中我们存入的有这些岛屿的位置,怎样判断是水还是岛屿?我们需要从新开一个数组book,用来标记,(切记初始化的时候,只需要把岛屿位置当作下标,标记为1,其余的都为0)我们在查询时,发现有淹的岛屿,需要把他标记为0,就这么多,代码奉上。


#include <stdio.h>#include <string.h>#include <algorithm>using namespace std ;#define maxt 500000+10int book[maxt];int a[maxt];struct note1{    int a;    int b;} Q[maxt];struct note2{    int x;    int y;} q[maxt];bool cmp1(note1 t1,note1 t2){    return t1.a<t2.a;}bool cmp2(note2 t1,note2 t2){    return t1.x<t2.x;}int main(){    int n,m;    while(~scanf("%d %d",&n,&m))    {        memset(book,0,sizeof(book));        for(int i=1; i<=n; i++)        {            scanf("%d",&Q[i].a);            book[i]=1;            Q[i].b=i;        }        sort(Q+1,Q+n+1,cmp1);        for(int j=1; j<=m; j++)        {            scanf("%d",&q[j].x);            q[j].y=j;        }        sort(q+1,q+m+1,cmp2);        int maxn=0,cont=1,j=1;        for(int i=1; i<=m; i++)        {            if(q[i].x<=maxn)            {                a[q[i].y]=cont;            }            else            {                maxn=q[i].x;                while(j<=n&&Q[j].a<=q[i].x)                {                    if(book[Q[j].b]&&book[Q[j].b+1]&&book[Q[j].b-1]) cont++;                    if(book[Q[j].b]&&!book[Q[j].b+1]&&!book[Q[j].b-1])cont--;                    book[Q[j].b]=0;                    j++;                }                a[q[i].y]=cont;            }        }        for(int i=1; i<=m; i++)            printf("%d\n",a[i]);    }    return 0;}



原创粉丝点击