Poj 2187 Beauty Contest(旋转卡壳)
2012-12-20 11:57
417 查看
题目链接: http://poj.org/problem?id=2187
题意:给定平面上的一些散点集,求最远两点距离的平方值。
思路:Graham水平序。极角序判断共线很麻烦,可以参考这里http://blog.csdn.net/lyy289065406/article/details/6648617
虽然原题说 No two farms share the same pair of coordinates 但好像poj加入了重点。。。
参考了这里的代码http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html
这个题加深了我对凸包算法一些细节的理解。有时间再用Melkman做一下
贴一下大牛的快速凸包算法代码。速度没有Graham水平序快
题意:给定平面上的一些散点集,求最远两点距离的平方值。
思路:Graham水平序。极角序判断共线很麻烦,可以参考这里http://blog.csdn.net/lyy289065406/article/details/6648617
虽然原题说 No two farms share the same pair of coordinates 但好像poj加入了重点。。。
参考了这里的代码http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html
这个题加深了我对凸包算法一些细节的理解。有时间再用Melkman做一下
#include <iostream> #include <cmath> #include <algorithm> using namespace std; #define max(x,y) ((x)>(y)?(x):(y)) const int NUM=50005; struct Point { int x,y; void get () { scanf("%d%d",&x,&y); } bool operator < (const Point& _P) const { return y<_P.y||(y==_P.y&&x<_P.x); }; }pt[NUM],ch[NUM]; int cross (Point p,Point q,Point x) { return (p.x-x.x)*(q.y-x.y)-(q.x-x.x)*(p.y-x.y); } int dist2 (Point a,Point b) { return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); } void Graham (Point pt[],Point ch[],int &len,int n) { int i,top=1; sort(pt,pt+n); ch[0]=pt[0]; ch[1]=pt[1]; for (i=2;i<n;i++) { while (top>0 && cross(ch[top],pt[i],ch[top-1]) <= 0) top--; ch[++top]=pt[i]; } int temp=top; for (i=n-2;i>=0;i--) { while (top>temp && cross(ch[top],pt[i],ch[top-1]) <= 0) top--; ch[++top]=pt[i]; } len=top; } int Rotating_Calipers (Point ch[],int n) { int q=1,ans=0; ch =ch[0]; for (int p=0;p<n;p++) { while (cross(ch[p+1],ch[q+1],ch[p]) > cross(ch[p+1],ch[q],ch[p])) q=(q+1)%n; ans=max(ans,max(dist2(ch[p],ch[q]),dist2(ch[p+1],ch[q+1]))); } return ans; } int main () { int n,len; while (~scanf("%d",&n)) { for (int i=0;i<n;i++) pt[i].get(); Graham(pt,ch,len,n); printf("%d\n",Rotating_Calipers(ch,len)); } return 0; } /* 4 0 0 1 0 2 0 -1 0 Out 9 */ /* 10 4 3 0 0 0 3 0 2 2 2 3 3 3 0 3 4 3 1 5 5 Out 50 */
贴一下大牛的快速凸包算法代码。速度没有Graham水平序快
//快速凸包算法(Quickhull Algorithm) #include <iostream> #include <cmath> #define STD 1e-12 #define cmp(a,b) (a.x<b.x || DB(a.x-b.x)==0 && a.y<b.y) using namespace std; const int NUM=50005; struct Point { double x,y; }p[NUM],ch[NUM]; double s[NUM]; int len=1,n; int DB (double x) { if (x>STD) return 1; if (x<-STD) return -1; return 0; } double cross (Point& o, Point& a, Point& b) { return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x); } //ch[1]~ch[len]存储凸包 void Quickhull (int l,int r,Point a,Point b) { int x=l,i=l-1,j=r+1,k; for (k=l;k<=r;k++) { double temp=DB(s[x]-s[k]); if (temp<0 || temp==0 && cmp(p[x],p[k])) x=k;//找距离最远点 } Point y=p[x]; for (k=l;k<=r;k++) { s[++i]=cross(p[k],a,y); if (DB(s[i])>0) //划分点集 swap(p[i],p[k]); else i--; } for (k=r;k>=l;k--) { s[--j]=cross(p[k],y,b); if (DB(s[j])>0) //划分点集 swap(p[j],p[k]); else j++; } if (l<=i) Quickhull(l,i,a,y); ch[++len]=y; if (j<=r) Quickhull(j,r,y,b); } double dis2 (Point a,Point b) { return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int main () { int i,j,x=0; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%lf%lf",&p[i].x,&p[i].y); if (x==0 || cmp(p[i],p[x])) x=i; } swap(p[1],p[x]); ch[1]=p[1]; Quickhull (2,n,p[1],p[1]); double ans=0; for (i=1;i<=len;i++) for (j=i+1;j<=len;j++) { double tmp=dis2(ch[i],ch[j]); if (tmp > ans) ans=tmp; } printf("%.0lf\n",ans); return 0; }
相关文章推荐
- poj 2187:Beauty Contest(旋转卡壳)
- poj 2187 Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest 构造凸包 + 旋转卡壳
- POJ 2187 Beauty Contest 构造凸包 + 旋转卡壳
- POJ 2187: Beauty Contest(旋转卡壳)
- 【凸包】poj 2187 Beauty Contest (旋转卡壳求平面最远点对)
- 【POJ】2187 Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest(旋转卡壳)
- POJ 2187:Beauty Contest (凸包+旋转卡壳)
- POJ2187:Beauty Contest(凸包 & 旋转卡壳)
- [POJ 2187]Beauty Contest(旋转卡壳)
- poj 2187 Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest(旋转卡壳)
- poj 2187 Beauty Contest(旋转卡壳求最远点对)
- POJ 2187 Beauty Contest(旋转卡壳求点凸包直径)
- POJ 2187 Beauty Contest(旋转卡壳模板题)
- POJ 2187: Beauty Contest(旋转卡)
- hdu-2187 Beauty Contest(旋转卡壳求平面最远点对)
- poj-2187-凸包-旋转卡壳法求直径
- poj2187 凸包上的最远点对的距离(凸包+旋转卡壳)