SWUST0249 (凸包面积)

  1 type node=record x,y:longint; end;
  2 const maxn=3008;
  3 var k,q,qq:longint;
  4     sum:double;
  5     f,g:array[0..maxn] of node;
  6     m,i,j,a,b:longint;
  7     stack:array[0..maxn] of longint;
  8     nm:longint;
  9 function dis(a,b:node):double;
 10 begin
 11     exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)));
 12 end;
 13 procedure swap(var a,b:node); inline;
 14 var c:node;
 15 begin
 16     c:=a; a:=b; b:=c;
 17 end;
 18 function dig(a,b:node):longint; inline;
 19 begin
 20     exit(a.x*b.y-a.y*b.x);
 21 end;
 22 function mk(a,b:node):node; inline;
 23 begin
 24     mk.x:=b.x-a.x;
 25     mk.y:=b.y-a.y;
 26 end;
 27 function cmp(a,b:node):boolean; inline;
 28 var p1,p2:node;
 29 begin
 30     p1:=mk(f[1],a);
 31     p2:=mk(f[1],b);
 32     if dig(P1,P2)<0 then exit(true);
 33     if dig(P1,P2)=0 then
 34         if dis(f[1],a)>dis(f[1],b) then
 35             exit(true);
 36     exit(false);
 37 end;
 38 procedure sort(l,r:longint);
 39 var i,j:longint;
 40     x:node;
 41 begin
 42     i:=l; j:=r; x:=f[(l+r) div 2];
 43     while i<=j do
 44     begin
 45         while cmp(f[i],x) do inc(i);
 46         while cmp(x,f[j]) do dec(j);
 47         if i<=j then
 48         begin
 49             swap(f[i],f[j]);
 50             inc(i); dec(j);
 51         end;
 52     end;
 53     if l<j then sort(l,j);
 54     if i<r then sort(i,r);
 55 end;
 56 begin
 57     readln(q);
 58     for qq:=1 to q do
 59     begin
 60         readln(m);
 61         for i:=1 to m do readln(f[i].x,f[i].y);
 62         if m=2 then begin writeln('0.0'); continue; end;
 63         j:=1;
 64         for i:=2 to m do
 65             if (f[i].y<f[j].y) or (f[i].y=f[j].y) and (f[i].x<f[j].x) then
 66                 j:=i;
 67         swap(f[1],f[j]);
 68         sort(2,m);
 69         k:=2;
 70         g[1]:=f[1]; g[2]:=f[2];
 71         for i:=3 to m do
 72             if dig(mk(f[1],f[i]),mk(f[1],f[i-1]))<>0 then
 73             begin
 74                 inc(k);
 75                 g[k]:=f[i];
 76             end;
 77         nm:=3;
 78         stack[1]:=1; stack[2]:=2; stack[3]:=3;
 79         for i:=4 to k do
 80         begin
 81             a:=stack[nm-1];
 82             b:=stack[nm];
 83             while dig(mk(g[a],g[b]),mk(g[a],g[i]))>0 do
 84             begin
 85                 dec(nm);
 86                 a:=stack[nm-1];
 87                 b:=stack[nm];
 88             end;
 89             inc(nm);
 90             stack[nm]:=i;
 91         end;
 92         sum:=0;
 93         while nm>=3 do
 94         begin
 95             a:=stack[nm];
 96             b:=stack[nm-1];
 97             sum:=sum+abs(dig(mk(g[1],g[b]),mk(g[1],g[a])))/2;
 98             dec(nm);
 99         end;
100         writeln(sum:0:1);
101     end;
102 end.

 

posted @ 2015-06-13 14:43  rpSebastian  阅读(222)  评论(0编辑  收藏  举报