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

凸包模板

时间:2018-08-19 19:06:52      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:turn   node   向量   ble   参考   html   div   pre   size   

凸包模板

写在前面:预备函数

参考博客:https://www.cnblogs.com/nyist-TC-LYQ/p/7208054.html

一、 点的定义:

1     int n,tot;//n为二维平面上点的个数,tot为凸包上点的个数  
2     struct node  
3     {  
4         int x,y;  
5     }a[N],p[N];//p[]用来储存凸包  

 

二、距离公式:

1 double dis(node a,node b)  
2 {  
3     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);  
4 } 

 

三、叉积:返回结果为正说明p2在向量p0p1的左边(三点构成逆时针方向);返回结果为说明p2在向量p0p1的右边(三点构成顺时针方向)返回结果为0则三点共线(叉积的性质很重要)

 

1     double multi(node p0,node p1,node p2)  
2     {  
3         return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);  
4     }  

 

 

四、极角排序:根据坐标系内每一个点与x轴所成的角,逆时针比较,按照角度从小到大排序。

 

1     int cmp(node p1,node p2)//极角排序;  
2     {  
3         int x=multi(p1,p2,a[0]);  
4         if(x>0||(x==0&&dis(p1,a[0])<dis(p2,a[0]))) return 1;  
5         return 0;  
6     }  

 

 

重点和核心:graham 算法:O(nlogn)

 1     void Graham()  
 2     {  
 3         int k=0;          
 4         for(int i=0;i<n;i++)  
 5             if(a[i].y<a[k].y||(a[i].y==a[k].y&&a[i].x<a[k].x)) k=i;  
 6         swap(a[0],a[k]);  
 7         sort(a+1,a+n,cmp);  
 8         tot=2,p[0]=a[0],p[1]=a[1];  
 9         for(int i=2;i<n;i++)  
10         {  
11             while(tot>1&&multi(p[tot-1],p[tot-2],a[i])>=0) tot--;  
12             p[tot++]=a[i];  
13         }  
14     }  

 

 

  以上连接起来就是求凸包的模板。

 

凸包模板

标签:turn   node   向量   ble   参考   html   div   pre   size   

原文地址:https://www.cnblogs.com/weixq351/p/9502062.html

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