离散化——USACO 岛屿

nkoj 1279

Description

每当下雨时,FJ的牧场都会进水。由于牧场地面高低不平,被水淹没的地方不是很统一,形成一些岛屿。 

FJ的牧场可描述成一个一维的地形图,由N(1 <= N <= 100,000)个彼此相连的柱状的高度值组成。高度值为H(1)...H(n),(1 <= H(i) <= 1,000,000,000) 。假定这个地形图的两端有两条无限高的墙围着。 

当雨一直下时,地形图上最低的区域先被水淹没,形成一些不相邻的岛屿。一旦水面高度到达一个区域的高度,则认为这个区域被淹没。 
离散化——USACO 岛屿_第1张图片 

左图,在当前水面时,有4个岛屿。右图,在水面升高后,剩下2个岛屿。显然,最终所有的区域都会沉入水面。 
算出当雨从开始下到最后所有岛屿沉入水中,最多时可形成多少个岛屿。

分析:

离散化排序处理后,逐个淹没,对每一个建筑:

如果两边的建筑都被淹没,则该建筑被淹没后岛屿消失,ans--;

如果只有一边被淹没,岛屿只是变小,ans不变;

如果两边都没有被淹没,该岛屿被一分为二,ans++;

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
bool sink[100005];   //标记i号建筑是否被淹没 
struct land{
	int h,id;  //h表示高度,id表示排序前的序号 
	bool operator < (const land &a)const{
		return h<a.h;
	}
}s[100005]; 
int main(){
	int n,i,k,j,ans=1,cur=1;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&s[i].h);
		s[i].id=i;
	}
	sort(s+1,s+1+n);  
	sink[0]=sink[n+1]=true;
	for(i=j=1;i<=n;i++){
		while(s[j].h==s[i].h){   //注意处理相同高度的情况 
			sink[s[j].id]=true;
			if(sink[s[j].id-1]&&sink[s[j].id+1])cur--;  //两边都被淹没了,该岛屿消失 
			else if(!sink[s[j].id-1]&&!sink[s[j].id+1])cur++;  //两边都没淹没,岛屿一分为二 
			j++;
		}
		ans=max(ans,cur);   //更新答案 
	} 
	printf("%d",ans);
}


你可能感兴趣的:(离散化——USACO 岛屿)