前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法模板——计算几何2(二维凸包——Andrew算法)

算法模板——计算几何2(二维凸包——Andrew算法)

作者头像
HansBug
发布2018-04-11 10:40:40
5030
发布2018-04-11 10:40:40
举报
文章被收录于专栏:HansBug's LabHansBug's Lab

实现功能:求出二维平面内一对散点的凸包(详见Codevs 1298)

很神奇的算法——先将各个点按坐标排序,然后像我们所知的那样一路左转,求出半边的凸包,然后反过来求另一半的凸包

我以前正是因为总抱着想一步到位的想法,所以每次都跪得很惨(HansBug:事实上这次是我这辈子第一次A掉凸包题)

然后别的没了,就是凸包的基本思想

(顺便输出凸包周长C和面积S)

代码语言:javascript
复制
 1 type arr=array[0..100005] of longint;
 2 var
 3    i,j,k,l,m,n,m1,m2:longint;
 4    a:array[0..100005,1..2] of longint;
 5    b,c,d:arr;ans,are:extended;
 6 procedure swap(var x,y:longint);
 7           var z:longint;
 8           begin
 9                z:=x;x:=y;y:=z;
10           end;
11 procedure sort(l,r:longint);
12           var i,j,x,y:longint;
13           begin
14                i:=l;j:=r;x:=a[(l+r) div 2,1];y:=a[(l+r) div 2,2];
15                repeat
16                      while (a[i,1]<x) or ((a[i,1]=x) and (a[i,2]<y)) do inc(i);
17                      while (a[j,1]>x) or ((a[j,1]=x) and (a[j,2]>y)) do dec(j);
18                      if i<=j then
19                         begin
20                              swap(a[i,1],a[j,1]);
21                              swap(a[i,2],a[j,2]);
22                              inc(i);dec(j);
23                         end;
24                until i>j;
25                if i<r then sort(i,r);
26                if l<j then sort(l,j);
27           end;
28 function right(x1,y1,x2,y2:longint):boolean;
29          begin
30               exit((x1*y2)>(x2*y1));
31          end;
32 function trip(x1,y1,x2,y2,x3,y3:longint):boolean;
33          begin
34               exit(right(x2-x1,y2-y1,x3-x2,y3-y2));
35          end;
36 function check(x,y,z:longint):boolean;
37          begin
38               exit(trip(a[x,1],a[x,2],a[y,1],a[y,2],a[z,1],a[z,2]));
39          end;
40 procedure doit(var b:arr;var m:longint);
41           begin
42                b[1]:=d[1];b[2]:=d[2];j:=2;
43                for i:=3 to n do
44                    begin
45                         while (j>1) and not(check(b[j-1],b[j],d[i])) do dec(j);
46                         inc(j);b[j]:=d[i];
47                    end;
48                m:=j;
49           end;
50 begin
51      readln(n);
52      for i:=1 to n do readln(a[i,1],a[i,2]);
53      sort(1,n);j:=1;
54      for i:=2 to n do  //去重
55          begin
56               if (a[i,1]<>a[j,1]) or (a[i,2]<>a[j,2]) then
57                  begin
58                       inc(j);
59                       a[j,1]:=a[i,1];a[j,2]:=a[i,2];
60                  end;
61          end;
62      n:=j;
63     //求凸包
64      for i:=1 to n do d[i]:=i;doit(b,m1);
65      for i:=1 to n do d[i]:=n+1-i;doit(c,m2);
66     //两个半边整合
67      for i:=1 to m1 do d[i]:=b[i];
68      for i:=2 to m2 do d[i+m1-1]:=c[i];
69     //开始计算周长+面积
70      m:=m1+m2-2;ans:=0;are:=0;
71      for i:=1 to m do ans:=ans+sqrt(sqr(a[d[i],1]-a[d[i+1],1])+sqr(a[d[i],2]-a[d[i+1],2]));  //周长
72      for i:=1 to m do are:=are+a[d[i],1]*a[d[i+1],2]-a[d[i],2]*a[d[i+1],1];  //面积
73      are:=abs(are)/2;
74      writeln('Convex Hull:');
75      for i:=1 to m do writeln(a[d[i],1],' ',a[d[i],2]);
76      writeln('C = ',ans:0:1);
77      writeln('S = ',are:0:1);
78      readln;
79 end.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-04-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档