您的位置:首页 > 其它

岛屿的数量 51Nod - 1276

2017-08-04 20:51 190 查看
有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 4
2
1
3
2
3
0
1
3
2


Sample Output
1
2
0
2


思路:这个题做的我是一脸懵逼,开始的时候我用暴力,超时,后来又用结构体排序(我只用一个结构体)错误,很崩溃,最后上网查看大牛们的代码,才明白。(太考验思维,原谅我的智商)。
这个题需要用两个结构体,第一个存岛屿的高度,和岛屿的位置,后面用sortr按岛屿高度从小到大排序。第二个存查询高度,和查询的先后,再用sort按查询高度从小到大排序(这个大大减少的时间空间的复杂度)。如果按照这样排序,我们可以从小到大,查询一遍即可(已经查询过的就不需要在查了)(真的很难想到)。

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

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std ;
#define maxt 500000+10

int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: