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.