学会用graham_scan扫描法求图包

具体流程:http://blog.csdn.net/tmljs1988/article/details/7259331

程序参考:http://baike.baidu.com/link?url=kr6ENdkbOdkZb7TeBAprp0xGinXlV6rHrGO8qQG8VMEEeSnmAZmxqYkJSYJ-8VGklFCUwmC7ZX5o1oyyYo_k4K

我写的程序(只求了周长,面积参考http://blog.csdn.net/tmljs1988/article/details/7259331):

const
   pi=3.1415926575;
   zero=1e-6;
var
  ans,m:extended;
  n,i,tot:longint;
  x,y:array[0..100000]of extended;
  zz,num:array[0..100000]of longint;
function ok(x,a,y,b:extended):longint;
begin
  if abs(x-a)<=zero then
   begin
     if abs(b-y)<=zero then exit(0);
     if b>y then exit(1)
     else exit(2);
   end
  else
   if x<a then exit(1)
    else exit(2);
end;
procedure qsort(l,r:longint);
var
  i,j:longint;
  a,b,t:extended;
begin
  i:=l;j:=r;
  a:=x[(l+r)shr 1];
  b:=y[(l+r)shr 1];
  repeat
    while ok(x[i],a,y[i],b)=1 do i:=i+1;
    while ok(x[j],a,y[j],b)=2 do j:=j-1;
    if i<=j then
     begin
       t:=x[i];x[i]:=x[j];x[j]:=t;
       t:=y[i];y[i]:=y[j];y[j]:=t;
       i:=i+1;j:=j-1;
     end;
  until i>j;
  if i<r then qsort(i,r);
  if j>l then qsort(l,j);
end;
function plot(x1,x2,y1,y2:extended):extended;
begin
  plot:=x1*y2-x2*y1;
end;
function check(first,last,new:longint):boolean;
var
  ax,ay,bx,by:extended;
begin
  ax:=x[last]-x[first];ay:=y[last]-y[first];
  bx:=x[new]-x[last];by:=y[new]-y[last];
  if plot(ax,ay,bx,by)<-zero then exit(true)
   else exit(false);
end;
procedure TB;
var
  i,j,tail:longint;
begin
  tot:=0;
  zz[1]:=1;tail:=1;
  for i:=2 to n do
   begin
     while (zz[tail]<>1) and check(zz[tail-1],zz[tail],i) do dec(tail);
     inc(tail);
     zz[tail]:=i;
   end;
  tot:=tot+tail-1;
  for i:=1 to tail-1 do
   num[i]:=zz[i];
  zz[1]:=n;tail:=1;
  for i:=n-1 downto 1 do
   begin
     while (zz[tail]<>n) and check(zz[tail-1],zz[tail],i) do dec(tail);
     inc(tail);
     zz[tail]:=i;
   end;
  for i:=1 to tail-1 do
   num[tot+i]:=zz[i];
  tot:=tot+tail-1;
end;
function dist(a,b:longint):extended;
begin
  dist:=sqrt(sqr((x[a]-x[b]))+sqr((y[a]-y[b])));
end;
begin
  readln(n,m);
  for i:=1 to n do readln(x[i],y[i]);
  qsort(1,n);
  TB;
  for i:=1 to tot-1 do
   ans:=ans+dist(num[i],num[i+1]);//求周长
  write(trunc(ans));
end.


你可能感兴趣的:(学会用graham_scan扫描法求图包)