HDU1542Atlantis

Posted 蒟蒻LQL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1542Atlantis相关的知识,希望对你有一定的参考价值。

题意

   给出n个矩形的左下角和右上角的坐标,计算总的面积(相交部分只算一次)。

分析

   线段树扫描线的模板题。

   将每个矩形都拆成上下两条线段,然后从下网上扫,当遇到底边时就加上这个区间,遇到顶边时,就减去这个区间。这些都很好理解,但是有一个点我感觉很难受!对于普通线段树,先将区间[1,2]+1,再更新区间[2,3]+1的话,2这个点的值应该是2。但是扫描线来说,2应该是1。因为[1,3]是一条线。我们的解决办法是,在线段树[L,R]的区间内储存[L,R+1]的值

  

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 const int maxn=200;
 8 struct Node{
 9     double l,r,h;
10     int state;
11     bool operator <(const Node & rhs)const{
12         return h<rhs.h;
13     }
14     Node (){}
15     Node (double l,double r,double h,int state):l(l),r(r),h(h),state(state){}
16 }node[maxn];
17 double v[maxn];
18 int n,kase;
19 double x1,y1,x2,y2,ans;
20 double sumv[4*maxn];
21 int cover[4*maxn];
22 
23 void maintain(int o,int L,int R){
24     if(cover[o])
25         sumv[o]=v[R+1]-v[L];
26     else if(L==R)
27         sumv[o]=0;
28     else
29         sumv[o]=sumv[2*o]+sumv[2*o+1];
30 }
31 int ql,qr,vv;
32 void update(int o,int L,int R){
33     if(ql<=L&&qr>=R){
34         cover[o]+=vv;
35         maintain(o,L,R);
36         return ;
37     }
38     int M=L+(R-L)/2;
39     if(ql<=M)update(2*o,L,M);
40     if(qr>M)update(2*o+1,M+1,R);
41     maintain(o,L,R);
42 }
43 int main(){
44     kase=0;
45     while(scanf("%d",&n)!=EOF&&n){
46         int sz=0;
47         ++kase;
48         for(int i=1;i<=n;i++){
49             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
50             node[++sz].l=x1,node[sz].r=x2,node[sz].h=y1,node[sz].state=1,v[sz]=x1;
51             node[++sz].l=x1,node[sz].r=x2,node[sz].h=y2,node[sz].state=-1,v[sz]=x2;
52         }
53         sort(node+1,node+1+sz);
54         sort(v+1,v+1+sz);
55         int N=unique(v+1,v+1+sz)-v-1;
56         memset(sumv,0,sizeof(sumv));
57         memset(cover,0,sizeof(cover));
58         ans=0;
59         for(int i=1;i<sz;i++){
60             ql=lower_bound(v+1,v+1+N,node[i].l)-v,qr=lower_bound(v+1,v+1+N,node[i].r)-v-1,vv=node[i].state;
61             update(1,1,N);
62             ans+=sumv[1]*(node[i+1].h-node[i].h);
63         }
64         printf("Test case #%d\n",kase);
65         printf("Total explored area: %.2f\n",ans);
66         printf("\n");
67     }
68 return 0;
69 }
View Code

 

以上是关于HDU1542Atlantis的主要内容,如果未能解决你的问题,请参考以下文章

HDU1542--Atlantis(扫描线)

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

HDU 1542 Atlantis

HDU 1542 Atlantis

HDU-1542 Atlantis 线段树+扫描线

HDU - 1542 Atlantis (扫描线+线段树)