poj 3335 Rotating Scoreboard

来源:互联网 发布:创意摆件 知乎 编辑:程序博客网 时间:2024/05/18 02:17

Description

This year, ACM/ICPC World finals will be held in a hall in formof a simple polygon. The coaches and spectators are seated alongthe edges of the polygon. We want to place a rotating scoreboardsomewhere in the hall such that a spectator sitting anywhere on theboundary of the hall can view the scoreboard (i.e., his line ofsight is not blocked by a wall). Note that if the line of sight ofa spectator is tangent to the polygon boundary (either in a vertexor in an edge), he can still view the scoreboard. You may viewspectator's seats as points along the boundary of the simplepolygon, and consider the scoreboard as a point as well. Yourprogram is given the corners of the hall (the vertices of thepolygon), and must check if there is a location for the scoreboard(a point inside the polygon) such that the scoreboard can be viewedfrom any point on the edges of the polygon.

Input

The first number in the input line, T is the number oftest cases. Each test case is specified on a single line of inputin the form n x1 y1x2 y2 ... xnyn where n (3 ≤ n ≤ 100) is thenumber of vertices in the polygon, and the pair of integersxi yi sequence specify thevertices of the polygon sorted in order.

Output

The output contains T lines, each corresponding to aninput test case in that order. The output line contains either YESor NO depending on whether the scoreboard can be placed inside thehall conforming to the problem conditions.

SampleInput

24 0 0 0 1 1 1 1 08 0 0  0 2  1 2  1 1  2 1  2 2  3 2  3 0

SampleOutput

YESNO

Source

Tehran 2006 Preliminary
 
求多边形是否有核。
还是半平面交,不过要判断面积为零的交是合法的、
 
 
AC CODE
 较1279改了一点点、、

programpku_3335;

consteps=1e-8;

typedotsty=record

             x,y:double;

           end;

    linesty=record

              x1,y1,x2,y2,k:double;

              sty:longint;

            end;

varline:array[1..100] of linesty;

   dot:array[1..100] of dotsty;

   q:array[1..100] of longint;

   n,cases:longint;

//============================================================================

procedureswap(x,y:longint);

vartt:linesty;

begin

  tt:=line[x];line[x]:=line[y]; line[y]:=tt;

end;

//============================================================================

procedureqsort(l,r:longint);

vark:double;

   i,j:longint;

begin

  k:=line[(l+r) shr 1].k;i:=l; j:=r;

  repeat

   while line[i].k>k do inc(i);

   while line[j].k<k do dec(j);

   if i<=j then

   begin

     swap(i,j);

     inc(i); dec(j);

   end;

  untili>j;

  if l<j thenqsort(l,j);

  if i<r thenqsort(i,r);

end;

//============================================================================

procedureinit;

vari,j:longint;

begin

  read(n);

  for i:=1 to n do

   read(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].x2) or

     ((line[i].x1=line[i].x2) and(line[i].y1<line[i].y2)) then

       line[i].sty:=1 else line[i].sty:=2;

   if line[i].x1<>line[i].x2then

     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

   whileline[i].sty=1 do inc(i);

   whileline[j].sty=2 do dec(j);

   ifi<=j then swap(i,j);

  until i>j;qsort(1,j); qsort(i,n);

end;

//============================================================================

functionleft(x,y:double; l:linesty):extended;

begin

 left:=(l.x2-l.x1)*(y-l.y1)-(x-l.x1)*(l.y2-l.y1);

end;

//============================================================================

functioncross(l1,l2:linesty):dotsty;

vars1,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;

  ifabs(ss)<eps then

  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;

//============================================================================

functionhalf_plane:double;

vartmp:dotsty;

   tt:double;

   i,be,en:longint;

   flag:boolean;

begin

  be:=1; en:=1;q[1]:=1;

  for i:=2 to n do

  begin

   ifsqr(line[i].x1-line[i].x2)+sqr(line[i].y1-line[i].y2)<epsthen continue;

   if abs(line[q[en]].k-line[i].k)<eps then

     if left(line[q[en]].x1,line[q[en]].y1,line[i])>-epsthen

       dec(en) else continue;

   while be<en do

   begin

     tmp:=cross(line[i],line[q[en]]);

     if tmp.x=maxlongint then exit(-1);

     if left(tmp.x,tmp.y,line[q[en-1]])>epsthen

       dec(en) else break;

   end;

   while be<en do

   begin

     if line[i].sty=1 then break;

     if line[i].k>line[q[be]].k-eps thenbreak;

     tmp:=cross(line[i],line[q[be]]);

     if tmp.x=maxlongint then exit(-1);

     if left(tmp.x,tmp.y,line[q[be+1]])>epsthen

       inc(be) else break;

   end;

   if be<en then

   begin

     tmp:=cross(line[i],line[q[en]]);

     if tmp.x=maxlongint then exit(-1);

     if left(tmp.x,tmp.y,line[q[be]])>eps thencontinue;

   end; inc(en); q[en]:=i;

  end; tt:=0;

  if en<be+2then exit(-1);

  for i:=be to en-1do

   dot[i]:=cross(line[q[i]],line[q[i+1]]);

 dot[en]:=cross(line[q[en]],line[q[be]]);

  for i:=be to en-1do

   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;

//============================================================================

procedurework;

vars:double;

begin

  init;

  s:=half_plane;

  if s<-epsthen writeln('NO') else writeln('YES');

end;

//============================================================================

begin

  readln(cases);

  for cases:=1 to cases dowork;

end.

0 0
原创粉丝点击