ZJU 1453 Surround the Trees 凸包

这次用的是Graham算法,算法如下:

1)qy坐标最小的点p0,若具有最小坐标的点有多个,则取最左边的点作为po.

2)q中剩余的点按逆时针相对p0的极角排序,若有数个保留其中距p0最远的点

 得到序列(p1,p2,...pn-1);

3)p0,p1,p2相继入栈

4)for i=3 to n-1 do

    1)while 由次栈顶元素、栈顶元素和Pi所形成角不是向左转do栈顶元素出栈s
    2)pi
入栈

5)打印按逆时针排列的栈中的各顶点

type
  lala=array[1..2] of longint;

var
  n,m1,i:longint;
  ans:real;
  u:lala;
  a,m:array[0..200,1..2] of longint;

function hehe(i,j:lala):boolean;
var
  s:longint;
begin
  if (i[1]=j[1])and(i[2]=j[2]) then exit(false);
  if (i[1]=u[1])and(i[2]=u[2]) then exit(true);
  if (j[1]=u[1])and(j[2]=u[2]) then exit(false);
  s:=(i[1]-u[1])*(j[2]-u[2])-(j[1]-u[1])*(i[2]-u[2]);
  if s<0 then exit(true);
  if s>0 then exit(false);
  if sqr(i[1]-u[1])+sqr(i[2]-u[2])>sqr(j[1]-u[1])*sqr(j[2]-u[2])
    then exit(true)
    else exit(false);
end;

procedure qsort(l,r:longint);
var
  i,j:longint;
  k:array[1..2] of longint;
begin
  if l>=r then exit;
  i:=l;
  j:=r;
  k:=a[(i+j) div 2];
  repeat
    while hehe(a[i],k) do inc(i);
    while hehe(k,a[j]) do dec(j);
    if i<=j then
    begin
      a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
      inc(i);dec(j);
    end;
  until i>j;
  qsort(i,r);
  qsort(l,j);
end;

function cj(k,i,j:lala):longint;
begin
  cj:=(i[1]-k[1])*(j[2]-k[2])-(j[1]-k[1])*(i[2]-k[2]);
end;

procedure tb;
var
  i:longint;
begin
  qsort(1,n);
  for i:=1 to 3 do
  begin
    inc(m1);
    m[m1]:=a[i];
  end;
  inc(n);
  a[n]:=u;
  for i:=4 to n do
  begin
    while cj(m[m1-1],m[m1],a[i])>=0 do dec(m1);
    inc(m1);
    m[m1]:=a[i];
  end;
end;

begin
  readln(n);
  while n>0 do
  begin
    m1:=0;
    for i:=1 to n do
      readln(a[i,1],a[i,2]);
    if n=1 then
    begin
      writeln('0.00');
      readln(n);
      continue;
    end;
    if n=2 then
    begin
      writeln(2*sqrt(sqr(a[1,1]-a[2,1])+sqr(a[2,1]-a[2,2])):0:2);
      readln(n);
      continue;
    end;
    u[1]:=maxlongint;
    u[2]:=maxlongint;
    for i:=1 to n do
      if (a[i,2]<u[2])or(a[i,2]=u[2])and(a[i,1]<u[1]) then u:=a[i];
    tb;
    ans:=0;
    for i:=2 to m1 do
      ans:=ans+sqrt(sqr(m[i,1]-m[i-1,1])+sqr(m[i,2]-m[i-1,2]));
    writeln(ans:0:2);
    readln(n);
  end;
end.




你可能感兴趣的:(ZJU 1453 Surround the Trees 凸包)