凸包——扫描法(水平序)
{ ID:tomson12 PROG:fc LANG:PASCAL } type point=record x,y:extended; end; const maxn=10001; var p,ch:array[0..maxn]of point; n:longint; procedure init; var i:longint; begin readln(n); for i:=1 to n do readln(p[i].x,p[i].y); end; procedure swap(var a,b:point); var t:point; begin t:=a; a:=b; b:=t; end; procedure qsort(l,r:longint); var i,j:longint; tx,ty:extended; begin i:=l; j:=r; tx:=p[(l+r)>>1].x; ty:=p[(l+r)>>1].y; repeat while (p[i].y<ty) or (p[i].y=ty) and (p[i].x<tx) do inc(i); while (p[j].y>ty) or (p[j].y=ty) and (p[j].x>tx) do dec(j); if i<=j then begin swap(p[i],p[j]); inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; function dist(p0,p1:point):extended; begin exit(sqrt(sqr(p0.x-p1.x)+sqr(p0.y-p1.y))); end; function cross(p0,p1,p2:point):extended; begin exit((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x)); end; procedure work; var i,k,m:longint; ans:extended; begin m:=0; for i:=1 to n do begin while (m>1) and (cross(ch[m-1],ch[m],p[i])<=0) do dec(m); inc(m); ch[m]:=p[i]; end; k:=m; for i:=n-1 downto 1 do begin while (m>k) and (cross(ch[m-1],ch[m],p[i])<=0) do dec(m); inc(m); ch[m]:=p[i]; end; if n>1 then dec(m); ans:=dist(ch[m],ch[1]); for i:=1 to m-1 do ans:=ans+dist(ch[i],ch[i+1]); writeln(ans:0:2); end; begin assign(input,'fc.in'); reset(input); assign(output,'fc.out'); rewrite(output); init; qsort(1,n); work; close(input); close(output); end.
posted on 2011-03-16 10:20 Skywalker_Q 阅读(545) 评论(0) 编辑 收藏 举报