码迷,mamicode.com
首页 > 其他好文 > 详细

Convex hull凸包

时间:2016-05-21 11:42:23      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

把一个平面上给出的点都包含进去的最小凸多边形。逆时针输出凸包的各个顶点。

 

1.Graham扫描法 (O(n*logn))-------旋转扫除的技术:

2.Jarvis march步进法(O(n*h))h为凸包的顶点数--------打包的技术

应用:求二维平面最远点对。

 

uva,109

技术分享
  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 
  7 struct node
  8 {
  9     double x,y;
 10     //便于求出初始点
 11     bool operator<(const node& a)const{
 12         return x<a.x || (x==a.x && y<a.y);
 13     }
 14 };
 15 
 16 
 17 typedef vector<node> Vnode;//凸包
 18 typedef vector<Vnode> VVnode;//凸包个数
 19 
 20 //叉积判断是否向左转。
 21 double Isleft(node& p0,node& p1,node& p2)
 22 {
 23     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 24 }
 25 
 26 //求凸包
 27 int Convex_hull(Vnode p,Vnode &h){
 28     int n=p.size();
 29     int k=0;
 30     //按x升序然后y升序排列
 31     sort(p.begin(),p.end());
 32     
 33     for(int i=0;i<n;i++){
 34 //上链
 35         while(k>=2 && Isleft(h[k-2],h[k-1],p[i])<=0)
 36             k--;
 37         h[k++]=p[i];
 38     }
 39     //下链
 40     for(int i=n-2,t=k+1;i>=0;i--){
 41         while(k>=t && Isleft(h[k-2],h[k-1],p[i])<=0)
 42             k--;
 43         h[k++]=p[i];
 44     }
 45     return k;
 46 }
 47 //检查是否在凸多边形内
 48 int check(Vnode h, node p) {
 49     int n = h.size();
 50     int i, j, c = 0;
 51     for (i = 0, j = n-1; i < n; j = i++)
 52         if ((((h[i].y <= p.y) && (p.y < h[j].y)) || ((h[j].y <= p.y) && (p.y < h[i].y))) && (p.x < (h[j].x - h[i].x) * (p.y - h[i].y) / (h[j].y - h[i].y) + h[i].x))
 53             c = !c;
 54     return c;
 55 }
 56 //根据题意求凸包面积
 57 double Area(Vnode p){
 58     int n=p.size();
 59     double s=0;
 60     
 61     for(int i=1;i<n;i++){
 62         s+=((p[i-1].x*p[i].y-p[i].x*p[i-1].y))/2;
 63     }
 64     return s;
 65 }
 66 
 67 
 68 int main()
 69 {
 70     int n;
 71     VVnode hull;
 72     
 73     while(cin>>n && n!=-1)
 74     {
 75         Vnode p(n);
 76         for(int i=0;i<n;i++)
 77             cin>>p[i].x>>p[i].y;
 78         
 79         Vnode h(n+1);
 80         n=Convex_hull(p,h);
 81         h.resize(n);
 82         hull.push_back(h);
 83     }
 84     
 85     node k;
 86     double a=0;
 87     while(cin>>k.x>>k.y){
 88         VVnode::iterator it;
 89         for(it=hull.begin();it<hull.end();it++)
 90         {
 91             if(check(*it,k))
 92             {
 93                 a+=Area(*it);
 94                 hull.erase(it);
 95                 break;
 96             }
 97         }
 98     }
 99 //输出时带两位小数
100     cout.precision(2);
101 //fixed固定格式,floatfield代表以浮点数输出
102     cout.setf(ios::fixed,ios::floatfield);
103     cout<<a<<endl;
104     
105     return 0;
106 }
View Code

 

Convex hull凸包

标签:

原文地址:http://www.cnblogs.com/do-it-best/p/5514166.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!