首页 > 代码库 > poj2187 旋转卡(qia)壳(ke)

poj2187 旋转卡(qia)壳(ke)

题意:求凸包的直径

 

关于对踵点对、旋转卡壳算法的介绍可以参考这里:

http://www.cnblogs.com/Booble/archive/2011/04/03/2004865.html

http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html

http://blog.csdn.net/ACMaker

 

这里使用了lrj的complex<double>大法来表示复数。

注意别忘了复数乘法的定义:(a+bi)*(c+di)=(ac-bd)+(bc+ad)i

 

技术分享
  1 #include <iostream>  2 #include <complex>  3 #include <algorithm>  4 #include <cstdio>  5 using namespace std;  6 typedef complex<double> Point;      //Point A:complex   x+yi  7 typedef Point Vector;  8 const double eps=1e-10;  9  10 int dcmp(double x)      //return  0:x==0  -1:x<0  1:x>0 11 { 12     if (fabs(x)<eps)    return 0; 13         else return x<0?-1:1; 14 } 15  16 bool operator == (const Point &A,const Point &B) 17 { 18     double ax=real(A),ay=imag(A),bx=real(B),by=imag(B); 19     return dcmp(ax-bx)==0 && dcmp(ay-by)==0; 20 } 21 /* 22 bool operator <  (const Point &A,const Point &B) 23 { 24     double ax=real(A),ay=imag(A),bx=real(B),by=imag(B); 25     return ((ax<bx)||(ax==bx && ay<by)); 26 } 27 */ 28 bool cmp(const Point &A,const Point &B) 29 { 30     double ax=real(A),ay=imag(A),bx=real(B),by=imag(B); 31     //return ((ax<bx)||(ax==bx && ay<by)); 32     int dx=dcmp(ax-bx),dy=dcmp(ay-by);   //return  0:ax==bx  -1:ax<bx  1:ax>bx 33     return ((dx==-1)||((dx==0)&&(dy==-1))); 34 } 35  36  37 double Dot(Vector A,Vector B)        //Ax*Bx+Ay*By 38 { 39     return real(conj(A)*B); 40 } 41  42 double Cross(Vector A,Vector B)     //Ax*By-Ay*Bx 43 { 44     return imag(conj(A)*B); 45 } 46  47 Vector Rotate(Vector A,double rad) 48 { 49     return A*exp(Point(0,rad)); 50 } 51  52 double Dist(Point A,Point B)        //distance^2 53 { 54     double ax=real(A),ay=imag(A),bx=real(B),by=imag(B); 55     //cout<<ax<<" "<<ay<<" "<<bx<<" "<<by<<" "<<(ax-bx)*(ax-bx)+(ay-by)*(ay-by)<<endl; 56     return ((ax-bx)*(ax-bx)+(ay-by)*(ay-by)); 57 } 58  59 double PolygonArea(Point *p,int n) 60 { 61     double area=0; 62     for (int i=1;i<n-1;i++) 63         area+=Cross(p[i]-p[0],p[i+1]-p[0]); 64     return area/2; 65 } 66  67 int convexhull(Point *p,int n,Point *ch) 68 { 69     sort(p,p+n,cmp); 70     int m=0; 71     for (int i=0;i<n;i++) 72     { 73         while (m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) 74             m--; 75         ch[m++]=p[i]; 76     } 77     int k=m; 78     for (int i=n-2;i>=0;i--) 79     { 80         while (m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) 81             m--; 82         ch[m++]=p[i]; 83     } 84     if (n>1)    m--; 85     return m; 86 } 87  88 double rotating_calipers(Point *ch,int num) 89 { 90     int q=1; 91     double ans=0; 92     ch[num]=ch[0]; 93     for(int p=0;p<num;p++) 94     { 95         while(Cross(ch[p+1]-ch[p],ch[q+1]-ch[p])>Cross(ch[p+1]-ch[p],ch[q]-ch[p])) 96             q=(q+1)%num; 97         ans=max(ans,max(Dist(ch[p],ch[q]),Dist(ch[p+1],ch[q+1]))); 98     } 99     return ans;100 }101 102 Point p[51000],ch[51000];103 int n,x,y;104 105 int main()106 {107     //freopen("in.txt","r",stdin);108     //freopen("ou.txt","w",stdout);109 110     while (cin>>n)111     {112         for (int i=0;i<n;i++)113         {114             cin>>x>>y;115             p[i]=Point(x,y);116         }117 118         int num=convexhull(p,n,ch);119         int ans=rotating_calipers(ch,num);120 121         //cout<<num<<" "<<ans<<endl;122 123         cout<<ans<<endl;124     }125     return 0;126 }
View Code

 

发现一个下载USACO Contest数据的好地方:http://iskren.info/tasks/USACO/

poj2187 旋转卡(qia)壳(ke)