poj 1151 Atlantis 线段树+离散化+扫描线

来源:互联网 发布:贵阳大数据产业博览会 编辑:程序博客网 时间:2024/05/23 16:55

题意:给出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.


0 0
原创粉丝点击