第一道凸包

采用Andrew算法,不论实现还是理解都非常简单

 1 var q,x,y:array[0..5010] of longint;
 2     i,j,k,m,n:longint;
 3     ans:double;
 4 
 5 procedure swap(var a,b:longint);
 6   var c:longint;
 7   begin
 8     c:=a;
 9     a:=b;
10     b:=c;
11   end;
12 
13 procedure sort(l,r: longint);
14   var i,j,p,q: longint;
15   begin
16     i:=l;
17     j:=r;
18     p:=x[(l+r) shr 1];
19     q:=y[(l+r) shr 1];
20     repeat
21       while (x[i]<p) or (x[i]=p) and (y[i]<q) do inc(i);
22       while (p<x[j]) or (p=x[j]) and (q<y[j]) do dec(j);
23       if not(i>j) then
24       begin
25         swap(x[i],x[j]);
26         swap(y[i],y[j]);
27         inc(i);
28         j:=j-1;
29       end;
30     until i>j;
31     if l<j then sort(l,j);
32     if i<r then sort(i,r);
33   end;
34 
35 function check(i,j,k:longint):longint;
36   begin
37     exit((y[i]-y[k])*(x[j]-x[k])-(y[j]-y[k])*(x[i]-x[k]));
38   end;
39 
40 function calc(i,j:longint):double;
41   begin
42     exit(sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j])));
43   end;
44 
45 begin
46   readln(n);
47   for i:=1 to n do
48     readln(x[i],y[i]);
49   sort(1,n);
50   m:=1;
51   q[1]:=1;
52   for i:=2 to n do
53   begin
54     while (m>1) and (check(i,q[m],q[m-1])<0) do dec(m);
55     inc(m);
56     q[m]:=i;
57   end;
58   k:=m-1;
59   for i:=n-1 downto 1 do
60   begin
61     while (m>k) and (check(i,q[m],q[m-1])<0) do dec(m);
62     inc(m);
63     q[m]:=i;
64   end;
65   for i:=2 to m do
66     ans:=ans+calc(q[i],q[i-1]);
67   writeln(ans:0:2);
68 end.
View Code

 

posted on 2014-07-12 20:47  acphile  阅读(165)  评论(0编辑  收藏  举报