2014大连市赛c题-求积水(整体思维)

来源:互联网 发布:淘宝优惠信息采集软件 编辑:程序博客网 时间:2024/04/28 03:50

一开始想用栈来做,栈要保存两个数:一为高度,二为横坐标,主要是比较当前值temp与下一个值next的大小:如果temp大或等于,就将temp压入栈中,否则,就比较next与栈中元素的大小:如果栈中元素小就出栈,并更新ans+=(栈值-temp)*(next横坐标 - 栈的横坐标-1),将temp更新为出栈的值,再继续检查下一个栈中值是否大于next;如果如果栈中元素>=,ans+=(栈值-next)*(next横坐标 - 栈的横坐标-1);最后令temp=next;

但这样做感觉时间不够,之后就用整体的思维来做:就是将整个城市都淹没,水之后慢慢流失,先计算最高层和次高层之间的积水,p0为两者之间横坐标较大的横坐标,p1为两者之间横坐标较小的横坐标;之后p1与p2之外的积水,计算积水时我有用到前n项和sum[n]=sum[n-1]+a[n];看来基础会在不经意间发挥作用;(在n==1的时候要进行特判)

(后记:可以用单调队列来解)

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int maxn=100010;struct node{    int p,h;};node pos[maxn];bool cmp(node a,node b){    if(a.h==b.h)return a.p>b.p;    return a.h>b.h;}int sum[maxn];int main(){    int T;    scanf("%d",&T);    while(T--){        int n;        scanf("%d",&n);        for(int i=0;i<n;i++){            scanf("%d",&pos[i].h);            pos[i].p=i;            if(i)sum[i]=sum[i-1]+pos[i].h;            else sum[i]=pos[i].h;        }        if(n==1){            printf("0\n");continue;        }        sort(pos,pos+n,cmp);        int p0=max(pos[0].p,pos[1].p);        int p1=min(pos[0].p,pos[1].p);        int ans=(p0-p1-1)*pos[1].h-(sum[p0-1]-sum[p1]);        for(int i=2;i<n;i++){            if(pos[i].p>p0){                ans+=(pos[i].p-p0-1)*pos[i].h-(sum[pos[i].p-1]-sum[p0]);                p0=pos[i].p;            }            else if(pos[i].p<p1){                ans+=(p1-pos[i].p-1)*pos[i].h-(sum[p1-1]-sum[pos[i].p]);                p1=pos[i].p;            }        }        printf("%d\n",ans);    }    return 0;}



0 1
原创粉丝点击