标签:col graham namespace ace div 坐标 for 角度 style
Graham算法模板
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1100; 9 const double pi=acos(-1.0); 10 struct node{ 11 double x,y; 12 }p[maxn],a[maxn]; 13 int n,tot; 14 15 //算距离 16 double dis(node a, node b){ 17 return hypot(a.x-b.x,a.y-b.y); 18 } 19 20 //return 正:p2在向量p0p1的左侧;return 负:p2在向量p0p1的右侧;return 0:三点共线 21 double multi(node p0,node p1,node p2){ 22 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 23 } 24 //极角排序:根据坐标系内每一个点与x轴所成的角,逆时针比较,按照角度从小到大排序 25 int cmp(node a, node b){ 26 int x=multi(a,b,p[0]); 27 if( x>0 || (x==0&& dis(a,p[0])<dis(b,p[0]))) return 1; 28 return 0; 29 } 30 31 void Graham(){ 32 int k=0; 33 for(int i=1;i<n;i++){ 34 if( p[i].y<p[k].y || (p[i].y==p[k].y&&p[i].x<p[k].x)) k=i; 35 } 36 swap(p[0],p[k]); 37 sort(p+1,p+n,cmp); 38 tot=2; 39 a[0]=p[0]; 40 a[1]=p[1]; 41 for(int i=2;i<n;i++){ 42 while( tot>1 && multi(p[i],a[tot-1],a[tot-2])>=0 ){//a[tot-2]在p[i]a[tot-1]的左侧或三点共线,则p[i]在a[tot-2]a[tot-1]的右侧,则a[tot-1]不是极点 43 tot--; 44 } 45 a[tot++]=p[i]; 46 } 47 } 48 49 int main() 50 { 51 int t; 52 scanf("%d",&t); 53 while( t-- ){ 54 double r; 55 scanf("%d%lf",&n,&r); 56 for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 57 Graham(); 58 } 59 return 0; 60 }
标签:col graham namespace ace div 坐标 for 角度 style
原文地址:https://www.cnblogs.com/wsy107316/p/12298258.html