51 Nod 1276 岛屿的数量
原题链接:题目-岛屿的数量 (51nod.com)
给了n个岛每个岛都有高度,这n个岛是相连的,q个查询,海平面高度,当小岛小于等于海平面高度时,小岛会被淹没。
先读入山峰的高度和位置用一个结构体封装,在用一个数组封装原山峰的高,这样做的目的是为了方便我们处理海平面的高度,对海平面高度集合与岛屿集合高度进行升序排序。
海平面高度>=第j个岛屿的高度意思就是这个岛沉下沉。
判断这个岛的左右是否都沉,都为0的话意思是都沉下去了,那么这个岛原先为一个单独的岛屿,现在沉了num-1。
如果左右都不为0,意思就是这三个原来都不是沉的那么说明他们原来属于一个大的岛屿,他下沉了就会多一个岛屿num+1。
切记把判定下沉岛屿的值赋为0,循环变量++。
上面是有代码转换的思想,下面思想转换代码:
首先发现最好的处理方式不是平常的读一个处理一个,而是全部读进来,做一次集中处理,进行一次遍历即可知道答案,其次考虑当处理过下沉的岛屿后,用不用减去当前海平面的高度,更新一下岛屿的高度,很显然是不用的。只有判定其下沉时,才会关联其高度。然后怎样判定岛屿的数量我们列一下情况设中间为下沉岛屿:010,111,110,011,110。找到特殊情况即可。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N=1e5+10; 6 int b[N],res[N]; 7 int n,q; 8 struct E 9 { 10 int a ; 11 int b; 12 }e[N]; 13 bool cmp(E x,E y) 14 { 15 return x.a<y.a; 16 } 17 struct E s[N]; 18 int main() { 19 scanf("%d %d",&n,&q); 20 for(int i=1;i<=n;i++) 21 { 22 scanf("%d",&e[i].a); 23 b[i]=e[i].a; //b数组保留的是原山峰的高 24 e[i].b=i; //保留元素组的位置 25 } 26 for(int i=1;i<=q;i++) 27 { 28 scanf("%d",&s[i].a); 29 s[i].b=i; 30 } 31 sort(e+1,e+n+1,cmp); 32 sort(s+1,s+q+1,cmp); 33 int j=1,num=1; 34 for(int i=1;i<=q;i++) 35 { 36 while(j<=n&&s[i].a>=e[j].a) //注意两个是已经排过序的 37 { 38 if(b[e[j].b-1]==0&&b[e[j].b+1]==0) 39 num--; 40 if(b[e[j].b-1]>0&&b[e[j].b+1]>0) 41 num++; 42 b[e[j].b]=0; 43 j++; 44 } //s是已经排过序的 s数组 a存的是海面高度 b存的是原来未经排序是s数组的位序 45 res[s[i].b]=num; 46 } 47 for(int i=1;i<=q;i++) 48 printf("%d\n",res[i]); 49 return 0; 50 }