题意:给出n个矩形的左下角和右上角,求所有矩形的总面积(被覆盖的不算)。
分析:这题可以单用离散化来做,不过时间复杂度较高,于是就换用了扫描线。
先把横坐标和纵坐标离散化,然后加边,每次统计扫描线上的边的长度和两条扫描线间的距离就好了。
我说的很简略,连我自己都看不懂。
注意:浮点数之间可以之间判断相等。
我是通过这个网址学会的:
http://blog.csdn.net/youngyangyang04/article/details/7787693
代码:
var n,i,a1,tot:longint; s,x1,x2,y1,y2,ans:real; bian:array[0..300,1..3] of real; b:array[0..300] of longint; a:array[0..300] of real; t:array[1..1000,1..3] of longint; procedure sort1; var i,j:longint; begin for i:=1 to n*2-1 do for j:=i+1 to n*2 do if bian[i,1]>bian[j,1] then begin bian[0]:=bian[i];bian[i]:=bian[j];bian[j]:=bian[0]; b[0]:=b[i];b[i]:=b[j];b[j]:=b[0]; end; end; procedure sort2; var i,j:longint; begin for i:=1 to n*2-1 do for j:=i+1 to n*2 do if a[i]>a[j] then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; end; end; procedure hehe(d,l,r:longint); var m:longint; begin t[d,1]:=l; t[d,2]:=r; t[d,3]:=0; if r-l=1 then exit; m:=(l+r) div 2; hehe(d*2,l,m); hehe(d*2+1,m,r); end; procedure insert(d:longint;l,r:real;z:longint); var m:longint; begin if t[d,2]-t[d,1]=1 then begin t[d,3]:=t[d,3]+z; if t[d,3]=0 then s:=s-r+l else if t[d,3]=z then s:=s+r-l; exit; end; m:=(t[d,1]+t[d,2]) div 2; if r<=a[m] then insert(d*2,l,r,z) else if l>=a[m] then insert(d*2+1,l,r,z) else begin insert(d*2,l,a[m],z); insert(d*2+1,a[m],r,z); end; end; begin readln(n); while n>0 do begin inc(tot); for i:=1 to n do begin readln(x1,y1,x2,y2); bian[i*2-1,1]:=y1; bian[i*2-1,2]:=x1; bian[i*2-1,3]:=x2; b[i*2-1]:=1; bian[i*2,1]:=y2; bian[i*2,2]:=x1; bian[i*2,3]:=x2; b[i*2]:=-1; a[i*2-1]:=x1; a[i*2]:=x2; end; sort1; sort2; a1:=n*2; for i:=1 to a1-1 do if a[i]=a[i+1] then begin dec(a1); a[i]:=maxlongint div 100; end; sort2; hehe(1,1,a1); s:=0; i:=1; bian[0,1]:=-1; bian[n*2+1,1]:=-1; ans:=0; while i<=n*2 do begin insert(1,bian[i,2],bian[i,3],b[i]); while bian[i,1]=bian[i+1,1] do begin inc(i); insert(1,bian[i,2],bian[i,3],b[i]); end; ans:=ans+(bian[i+1,1]-bian[i,1])*s; inc(i); end; writeln('Test case #',tot); writeln('Total explored area: ',ans:0:2); writeln; readln(n); end; end.