3044 矩形面积求并 - Wikioi


题目描述 Description

    输入n个矩形,求他们总共占地面积(也就是求一下面积的并)

输入描述 Input Description

    可能有多组数据,读到n=0为止(不超过15组)

    每组数据第一行一个数n,表示矩形个数(n<=100)

    接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标

输出描述 Output Description

    每组数据输出一行表示答案

样例输入 Sample Input

    2
    10 10 20 20
    15 15 25 25.5
    0

样例输出 Sample Output

    180.00

 

水题,我只是拿来练习扫描线的

  1 const
  2         maxn=110;
  3 type
  4         node=record
  5           l,r,lc,rc,cnt:longint;
  6           sum,cover:double;
  7         end;
  8 var
  9         tree:array[0..maxn*4]of node;
 10         x:array[0..maxn*2]of double;
 11         l,r,c:array[0..maxn*2]of longint;
 12         y,lll,rrr:array[0..maxn*2]of double;
 13         n,tot,ll,rr:longint;
 14         ans:double;
 15 
 16 procedure swap(var x,y:longint);
 17 var
 18         t:longint;
 19 begin
 20         t:=x;x:=y;y:=t;
 21 end;
 22 
 23 procedure swap(var x,y:double);
 24 var
 25         t:double;
 26 begin
 27         t:=x;x:=y;y:=t;
 28 end;
 29 
 30 procedure sort(l,r:longint);
 31 var
 32         i,j:longint;
 33         y:double;
 34 begin
 35         i:=l;
 36         j:=r;
 37         y:=x[(l+r)>>1];
 38         repeat
 39           while x[i]<y do
 40             inc(i);
 41           while x[j]>y do
 42             dec(j);
 43           if i<=j then
 44           begin
 45             swap(x[i],x[j]);
 46             inc(i);
 47             dec(j);
 48           end;
 49         until i>j;
 50         if i<r then sort(i,r);
 51         if j>l then sort(l,j);
 52 end;
 53 
 54 procedure build(l,r:longint);
 55 var
 56         now,mid:longint;
 57 begin
 58         inc(tot);
 59         now:=tot;
 60         tree[now].l:=l;
 61         tree[now].r:=r;
 62         with tree[now] do
 63           begin
 64             cover:=0;
 65             cnt:=0;
 66             if l=r then
 67             begin
 68               sum:=x[r+1]-x[r];
 69               lc:=0;
 70               rc:=0;
 71               exit;
 72             end;
 73             mid:=(l+r)>>1;
 74             lc:=tot+1;
 75             build(l,mid);
 76             rc:=tot+1;
 77             build(mid+1,r);
 78             sum:=x[r+1]-x[l];
 79           end;
 80 end;
 81 
 82 procedure sort2(ll,rr:longint);
 83 var
 84         i,j:longint;
 85         z:double;
 86 begin
 87         i:=ll;
 88         j:=rr;
 89         z:=y[(ll+rr)>>1];
 90         repeat
 91           while y[i]<z do
 92             inc(i);
 93           while y[j]>z do
 94             dec(j);
 95           if i<=j then
 96           begin
 97             swap(l[i],l[j]);
 98             swap(r[i],r[j]);
 99             swap(y[i],y[j]);
100             swap(c[i],c[j]);
101             inc(i);
102             dec(j);
103           end;
104         until i>j;
105         if i<rr then sort2(i,rr);
106         if j>ll then sort2(ll,j);
107 end;
108 
109 function find(k:double):longint;
110 var
111         l,r,mid:longint;
112 begin
113         l:=1;
114         r:=n*2;
115         while l<>r do
116           begin
117             mid:=(l+r)>>1;
118             if x[mid]=k then exit(mid);
119             if x[mid]>k then r:=mid-1
120             else l:=mid+1;
121           end;
122         exit(l);
123 end;
124 
125 procedure init;
126 var
127         i:longint;
128         x1,y1,x2,y2:double;
129 begin
130         read(n);
131         if n=0 then halt;
132         ans:=0;
133         tot:=0;
134         for i:=1 to n do
135           begin
136             read(x1,y1,x2,y2);
137             lll[i*2-1]:=x1;
138             rrr[i*2-1]:=x2;
139             y[i*2-1]:=y1;
140             c[i*2-1]:=1;
141             lll[i*2]:=x1;
142             rrr[i*2]:=x2;
143             y[i*2]:=y2;
144             c[i*2]:=-1;
145             x[i*2-1]:=x1;
146             x[i*2]:=x2;
147           end;
148         sort(1,n*2);
149         build(1,n*2-1);
150         for i:=1 to n*2 do
151           begin
152             l[i]:=find(lll[i]);
153             r[i]:=find(rrr[i]);
154           end;
155         sort2(1,n*2);
156 end;
157 
158 procedure insert(now,c:longint);
159 var
160         mid:longint;
161 begin
162         with tree[now] do
163           begin
164             if (ll<=l) and (rr>=r) then
165             begin
166               inc(cnt,c);
167               if cnt>0 then cover:=sum
168               else cover:=tree[lc].cover+tree[rc].cover;
169               exit;
170             end;
171             mid:=(l+r)>>1;
172             if ll<=mid then insert(lc,c);
173             if rr>mid then insert(rc,c);
174             if cnt>0 then cover:=sum
175             else cover:=tree[lc].cover+tree[rc].cover;
176           end;
177 end;
178 
179 procedure work;
180 var
181         i:longint;
182 begin
183         for i:=1 to n*2 do
184           begin
185             if y[i]<>y[i-1] then ans:=ans+tree[1].cover*(y[i]-y[i-1]);
186             ll:=l[i];
187             rr:=r[i]-1;
188             insert(1,c[i]);
189           end;
190         writeln(ans:0:2);
191 end;
192 
193 begin
194         while true do
195           begin
196             init;
197             work;
198           end;
199 end.
View Code

 

转载于:https://www.cnblogs.com/Randolph87/p/3688678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值