[POJ 2187]Beauty Contest(旋转卡壳)

来源:互联网 发布:算法分析 知识总结 编辑:程序博客网 时间:2024/05/16 17:15

题目链接

http://poj.org/problem?id=2187

题目大意

求平面上最远的两个点的距离的平方。

思路

裸凸包+旋转卡壳求凸包上最远点对。。。
注意旋转卡壳的很多细节,不然会WA。。。
其实这个题也是可以用O(n2)暴力水过的,因为数据太弱。。。

代码

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <cmath>#define MAXN 51000#define EPS 1e-6using namespace std;int n;int dcmp(double x){    if(fabs(x)<EPS) return 0;    if(x>EPS) return 1;    return -1;}struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}}points[MAXN],stack[MAXN];Point operator-(Point a,Point b){    return Point(a.x-b.x,a.y-b.y);}double operator*(Point a,Point b){    return a.x*b.x+a.y*b.y;}double dist(Point a,Point b){    return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int top=0;bool cmp(Point a,Point b){    if(!dcmp(a.x-b.x)) return a.y<b.y;    return a.x<b.x;}double cross(Point a,Point b) //a->b X a->c{    return a.x*b.y-b.x*a.y;}void Graham(){    sort(points+1,points+n+1,cmp);    for(int i=1;i<=n;i++)    {        while(top>=2&&dcmp(cross(stack[top]-stack[top-1],points[i]-stack[top-1])<=0)) top--; //!!!!        stack[++top]=points[i];    }    int tmp=top;    for(int i=n-1;i>=1;i--)    {        while(top>=tmp+1&&dcmp(cross(stack[top]-stack[top-1],points[i]-stack[top-1])<=0)) top--;        stack[++top]=points[i];    }}double rotcalip(){    double ans=0;    int p=2;    for(int i=1;i<=top;i++)    {        while(dcmp(cross(stack[i+1]-stack[i],stack[p]-stack[i])-cross(stack[i+1]-stack[i],stack[p+1]-stack[i]))<0) p=p%top+1; //!!!!!!我顶你个肺        ans=max(ans,max(dist(stack[p],stack[i]),dist(stack[p],stack[i+1])));    }    return ans;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%lf%lf",&points[i].x,&points[i].y);    Graham();    printf("%d\n",(int)rotcalip());    return 0;}
0 0
原创粉丝点击