hdu1542 矩形面积并

来源:互联网 发布:重庆智慧校园软件 编辑:程序博客网 时间:2024/06/09 17:24

http://acm.hdu.edu.cn/showproblem.php?pid=1542

看了几篇博客后总算理解了。。。

题意:给出n个矩形的左下角与右上角坐标,求矩形面积并

解题思路:


如图,两个矩形有平行于X轴的4条线段,对先4条线段的两端点X坐标离散化,然后按线段的高度由低到高更新线段树(线段树叶子节点为1~2,2~3等),
一开始是1~3,所以面积是2*h1(第2条线段高度-第1条线段高度),接着2~4,所以整个线段的oneMoreLen长度是3,面积是3*h2(第3条线段高度-第2条线段高度),
再到1~3,但这次是cover要加上-1,因为到顶,要减出来,面积是3*h3,结束。

其实就是对X坐标离散,建线段树,再一层一层计算面积。

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<iostream>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<bitset>using namespace std;#define ll __int64#define N 110struct line{    double left,right,h;    int flag;}L[2*N];map<double,int>M;double X[2*N];double XLi[2*N];int cmp(line aa,line bb){    return aa.h<bb.h;}struct node{    int left,right,cover;//cover表示该段成段覆盖的次数,但不向下更新    double oneMoreLen;//该区间覆盖一次以上的长度}seg_tree[N*4];void seg_built(int l,int r,int num){    seg_tree[num].left=l;    seg_tree[num].right=r;    seg_tree[num].cover=0;    seg_tree[num].oneMoreLen=0;    if(r!=l+1)    {        int mid=(l+r)>>1;        seg_built(l,mid,num<<1);        seg_built(mid,r,num<<1|1);    }}void push_up(int num)//向上更新{    if(seg_tree[num].cover>0)    {        seg_tree[num].oneMoreLen=XLi[seg_tree[num].right]-XLi[seg_tree[num].left];        return;    }    if(seg_tree[num].right==seg_tree[num].left+1)    {        seg_tree[num].oneMoreLen=0;    }    else    {        seg_tree[num].oneMoreLen=seg_tree[2*num].oneMoreLen+seg_tree[2*num+1].oneMoreLen;    }}void seg_update(int l,int r,int value,int num){    if(l>=seg_tree[num].right||r<=seg_tree[num].left) return;    if(l<=seg_tree[num].left&&r>=seg_tree[num].right)    {        seg_tree[num].cover+=value;        push_up(num);        return;    }    seg_update(l,r,value,2*num);    seg_update(l,r,value,2*num+1);    push_up(num);}int main(){    int i,j,k;    int n,m,t;    t=1;    while(scanf("%d",&n)!=EOF && n )    {        M.clear();        m=0;        for(i=1;i<=n;i++)        {            double x1,x2,y1,y2;            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            X[++m]=x1;            L[m].left=x1;            L[m].right=x2;            L[m].h=y1;            L[m].flag=1;//线段记录            X[++m]=x2;            L[m].left=x1;            L[m].right=x2;            L[m].h=y2;            L[m].flag=-1;//线段记录        }        sort(X+1,X+1+m);        sort(L+1,L+1+m,cmp);        M[X[1]]=1;        XLi[1]=X[1];        j=1;        for(i=2;i<=m;i++)//X坐标离散化        {            if(X[i]!=X[i-1])            {                M[X[i]]=++j;                XLi[j]=X[i];            }        }        seg_built(1,j,1);        double sum=0;        for(i=1;i<m;i++)        {            seg_update(M[L[i].left],M[L[i].right],L[i].flag,1);            sum+=seg_tree[1].oneMoreLen*(L[i+1].h-L[i].h);        }        printf("Test case #%d\nTotal explored area: %.2lf\n\n",t++,sum);    }}/*input:210 10 20 2015 15 25 25.50output:Test case #1Total explored area: 180.00*/


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快递被菜鸟驿站退回怎么办 电脑登录账户已锁定怎么办 被外管局查到境外汇款买房怎么办 军校生复检被刷怎么办 企业私刻章拿去挂项目怎么办? 中通快递被退回怎么办 网易邮箱提示被修复怎么办 小孩屁股烫红了怎么办 8岁近视400度怎么办 部队体能差的人怎么办 上环5天同房了怎么办 肾结石有3mm了怎么办 4*3mm肾结石好痛怎么办 做完肾结石积水后迟续发烧怎么办 血糖高有肾结石反复发高烧怎么办 肾里面有小结石怎么办 大于2厘米的结石怎么办 双肾结石肾盏扩张怎么办 边防消防警卫部队改革义务兵怎么办 汽车年检尾气复检不合格怎么办 车辆年检尾气不合格复检怎么办? 在瓜子上买车复检有问题怎么办 更换车壳车架号怎么办 吸完甲醛的绿萝怎么办 如果公务员复检不合格有异议怎么办 国考公务员政审没有毕业证怎么办 打针硬块4年不消怎么办 外墙补起来难看不好卖怎么办 杠精现实中应该怎么办 发现记者报道假新闻怎么办 2018消防兵转制到期士官怎么办 小孩睡觉老想着军训怎么办 1岁宝宝太老实了怎么办 上课小孩很调皮不听话怎么办 初中学生上课爱说话调皮怎么办 8个月婴儿疝气怎么办 头部疤痕不长发怎么办呢 有纹身想去当兵怎么办 在部队干活的钱怎么办 新兵5公里超过标准时间怎么办 17个月婴儿裹手怎么办