51Nod_1276 岛屿的数量【思维】

                                       51Nod_1276 岛屿的数量

                                http://www.51nod.com/Challenge/Problem.html#!#problemId=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}。

输入

第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)。

输出

输出共Q行,对应每个查询的岛屿数量。

样例输入

5 4
2
1
3
2
3
0
1
3
2

样例输出

1
2
0
2

分析

如果是孤立的岛屿,它被淹没后总数减一;如果它左边和右边相邻的岛屿都没被淹没,它被淹没后,总数加一;使用排序进行优化,具体看程序。

C++程序


#include<iostream>
#include<algorithm> 
#include<cstdio>

using namespace std;

const int N=50005;

struct Island{
	int h,id;
	//按小岛高度从小到大排序 
	bool operator <(const Island &t)const
	{
		return h<t.h;
	}
}a[N];

struct Query{
	int q,id;
	//按查询高度从小到大排序 
	bool operator <(const Query &t)const
	{
		return q<t.q;
	}
}Q[N];

int ans[N],v[N];//v[i]=true表示岛屿i被淹没 

int main()
{
	int n,q;
	scanf("%d %d",&n,&q);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i].h);
		a[i].id=i;
	}
	for(int i=0;i<q;i++)
	{
		scanf("%d",&Q[i].q);
		Q[i].id=i;
	}
	sort(a,a+n);
	sort(Q,Q+q);
	int sum=1,j=0; 
	for(int i=0;i<q;i++)
	{
		while(a[j].h<=Q[i].q&&j<n)
		{
			if(a[j].id==0)
			{//第一个岛屿 
			  if(v[1])
			    sum--;
			}
			else if(a[j].id==n-1)
			{//最后一个岛屿 
			  if(v[n-2])
			    sum--;
			}
			else
			{
				if(v[a[j].id-1]&&v[a[j].id+1])
				  sum--;
				else if(!v[a[j].id-1]&&!v[a[j].id+1])
				  sum++; 
			}
			v[a[j].id]=1;
			j++; 
		}
		ans[Q[i].id]=sum;
	}
	for(int i=0;i<q;i++)
	  cout<<ans[i]<<endl;
	return 0;
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值