poj 1279 Art Gallery

来源:互联网 发布:移动进销存软件 编辑:程序博客网 时间:2024/06/06 10:38

Description

The art galleries ofthe new and very futuristic building of the Center for BalkanCooperation have the form of polygons (not necessarily convex).When a big exhibition is organized, watching over all of thepictures is a big security concern. Your task is that for a givengallery to write a program which finds the surface of the area ofthe floor, from which each point on the walls of the gallery isvisible. On the figure 1. a map of a gallery is given in someco-ordinate system. The area wanted is shaded on the figure2.
poj <wbr>1279 <wbr>Art <wbr>Gallery

Input

The number of tasksT that your program have to solve will be on the first row of theinput file. Input data for each task start with an integer N, 5<= N <= 1500. Each of the next N rows of the input willcontain the co-ordinates of a vertex of the polygon ? two integersthat fit in 16-bit integer type, separated by a single space.Following the row with the co-ordinates of the last vertex for thetask comes the line with the number of vertices for the next testand so on.

Output

For each test youmust write on one line the required surface - a number with exactlytwo digits after the decimal point (the number should be rounded tothe second digit after the decimal point).

Sample Input

170 04 44 79 713 -18 -64 -4

Sample Output

80.00

Source

Southeastern Europe 2002
 
 
求多边形核的面积。
红果果的半平面交。题目保证顺时针读入。
 
特别需要注意的一点就是平行的判断。比较恶心啊、、视情况而定、、
 
ACCODE
 
programpku_1279;
const eps=1e-7;
type dotsty=record
             x,y:double;
           end;
    linesty=record
              x1,y1,x2,y2,k:double;
              sty:longint;
            end;
var line:array[1..1500] of linesty;
   dot:array[1..1500] of dotsty;
   q:array[1..1500] of longint;
   n,cases:longint;
//============================================================================
procedure swap(x,y:longint);
var tt:linesty;
begin
  tt:=line[x]; line[x]:=line[y];line[y]:=tt;
end;
//============================================================================
procedure qsort(l,r:longint);
var k:double;
   i,j:longint;
begin
  k:=line[(l+r) shr 1].k; i:=l; j:=r;
  repeat
    whileline[i].k>k do inc(i);
    whileline[j].k
    if i<=jthen
    begin
     swap(i,j);
     inc(i); dec(j);
    end;
  until i>j;
  if l
  if i
end;
//============================================================================
procedure init;
var i,j:longint;
begin
  readln(n);
  for i:=1 to n do
   readln(line[i].x1,line[i].y1);
  for i:=1 to n-1 doline[i].x2:=line[i+1].x1;
  for i:=1 to n-1 doline[i].y2:=line[i+1].y1;
  line[n].x2:=line[1].x1;line[n].y2:=line[1].y1;
  for i:=1 to n do
  begin
    if(line[i].x1
     ((line[i].x1=line[i].x2) and (line[i].y1
       line[i].sty:=1 else line[i].sty:=2;
    ifline[i].x1<>line[i].x2 then
     line[i].k:=(line[i].y1-line[i].y2)/(line[i].x1-line[i].x2)else
       line[i].k:=maxlongint;
  end; i:=1; j:=n;
  repeat
   while line[i].sty=1 doinc(i);
   while line[j].sty=2 dodec(j);
   if i<=j thenswap(i,j);
  until i>j; qsort(1,j); qsort(i,n);
end;
//============================================================================
function left(x,y:double; l:linesty):boolean;
begin
  if(l.x2-l.x1)*(y-l.y1)-(x-l.x1)*(l.y2-l.y1)>-eps then
    exit(true)else exit(false);
end;
//============================================================================
function cross(l1,l2:linesty):dotsty;
var s1,s2,ss,k,dx,dy:double;
begin
 s1:=(l2.x2-l1.x1)*(l1.y2-l1.y1)-(l1.x2-l1.x1)*(l2.y2-l1.y1);
 s2:=(l1.x2-l1.x1)*(l2.y1-l1.y1)-(l2.x1-l1.x1)*(l1.y2-l1.y1);
  ss:=s1+s2;
  if abs(ss)
  begin
   cross.x:=maxlongint; exit;
  end;
  k:=s1/ss;
  dx:=l2.x1-l2.x2; dy:=l2.y1-l2.y2;
  cross.x:=l2.x2+dx*k;
  cross.y:=l2.y2+dy*k;
end;
//============================================================================
function half_plane:double;
var tmp:dotsty;
   tt:double;
   i,be,en:longint;
   flag:boolean;
begin
  be:=1; en:=1; q[1]:=1;
  for i:=2 to n do
  begin
    ifabs(line[q[en]].k-line[i].k)
     if left(line[q[en]].x1,line[q[en]].y1,line[i]) then
       dec(en) else continue;
    whilebe
    begin
     tmp:=cross(line[i],line[q[en]]);
     if tmp.x=maxlongint then exit(0);
     if left(tmp.x,tmp.y,line[q[en-1]]) then
       dec(en) else break;
    end;
    whilebe
    begin
     if line[i].sty=1 then break;
     if line[i].k>line[q[be]].k-eps then break;
     tmp:=cross(line[i],line[q[be]]);
     if tmp.x=maxlongint then exit(0);
     if left(tmp.x,tmp.y,line[q[be+1]]) then
       inc(be) else break;
    end;
    if be
    begin
     tmp:=cross(line[i],line[q[en]]);
     if tmp.x=maxlongint then exit(0);
     if left(tmp.x,tmp.y,line[q[be]]) then continue;
    end;inc(en); q[en]:=i;
  end; tt:=0;
  if en
  for i:=be to en-1 do
   dot[i]:=cross(line[q[i]],line[q[i+1]]);
  dot[en]:=cross(line[q[en]],line[q[be]]);
  for i:=be to en-1 do
   tt:=tt+dot[i].x*dot[i+1].y-dot[i+1].x*dot[i].y;
 tt:=tt+dot[en].x*dot[be].y-dot[be].x*dot[en].y;
  tt:=abs(tt/2); exit(tt);
end;
//============================================================================
procedure work;
var s:double;
begin
  init;
  s:=half_plane;
  writeln(s:0:2);
end;
//============================================================================
begin
  assign(input,'1.in'); reset(input);
  readln(cases);
  for cases:=1 to cases do work;
end.
0 0
原创粉丝点击