首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

凸包+旋转卡壳-POJ 2187

2013-09-05 
凸包+旋转卡壳--POJ 2187题意:求平面点集上的最远点对思路:先求出凸包,最远的对肯定在凸包上面,但是下面暴

凸包+旋转卡壳--POJ 2187

题意:求平面点集上的最远点对

思路:先求出凸包,最远的对肯定在凸包上面,但是下面暴力的话时间复杂度o(n^2),旋转卡壳也是遍历,不过遍历的时候把复杂度降下来啦!

      旋转卡壳见:http://blog.csdn.net/hitfanyu/article/details/5522589

  

#include <iostream>#include<algorithm>#include<cmath>#include<cstdio>#include<cstdlib>#define eps 1e-8using namespace std;struct point{    int x,y;} p[50005],res[50005];int cross(point p0, point p1, point p2){    return(p1.x- p0.x) * (p2.y- p0.y) - (p1.y- p0.y) * (p2.x- p0.x);}int   dist(point a,point b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}bool cmp(point  a, point  b){    return(a.y< b.y|| (a.y== b.y&& a.x< b.x));}int Graham(int n){    int len, top=1;    sort(p, p+ n, cmp);    res[0] = p[0];    res[1] = p[1];    for(int i=2; i< n; i++)    {        while(top&& cross(res[top], res[top-1], p[i])<=eps)top--;        res[++ top] = p[i];    }    len= top;    res[++ top] = p[n-2];    for(int i= n-3; i>=0; i--)    {        while(top!= len&& cross(res[top], res[top-1], p[i])<=eps)top--;        res[++ top] = p[i];    }    return top;}int diameter(int n){    int i,j=1,ans=-1;    res[n]=res[0];    for(i=0; i<n; i++)    {        while(fabs(cross(res[i+1],res[j+1],res[i]))>fabs(cross(res[i+1],res[j],res[i]) ))            j=(j+1)%n;        ans=max(ans,max(dist(res[i],res[j]),dist(res[i+1],res[j+1])));    }    return ans;}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=0; i<n; i++)            cin  >> p[i].x >> p[i].y;        int top=Graham(n);        cout << diameter(top) << endl;    }    return 0;}


 

热点排行