POJ - 2187 Beauty Contest(最远点对)

Posted fht-litost

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 2187 Beauty Contest(最远点对)相关的知识,希望对你有一定的参考价值。

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

题意

给n个坐标,求最远点对的距离平方值。

分析

模板题,旋转卡壳求求两点间距离平方的最大值。

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d
",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define lc idx<<1
#define rc idx<<1|1
#define rson mid+1,r,rc
#define lson l,mid,lc
using namespace std;
typedef long long ll;
template <class T>
void test(T a) {
    cout<<a<<endl;
}
template <class T,class T2>
void test(T a,T2 b) {
    cout<<a<<" "<<b<<endl;
}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c) {
    cout<<a<<" "<<b<<" "<<c<<endl;
}
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 1e9+7;
int T;
void testcase() {
    printf("Case %d: ",++T);
}
const int MAXN = 50010;
const int MAXM = 30;
const double PI = acos(-1.0);
const double eps = 1e-7;

struct Point{
    int x,y;
    Point(int _x=0,int _y=0){
        x=_x,y=_y;
    }
    Point operator -(const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    int operator ^(const Point &b)const{
        return x*b.y-y*b.x;
    }
    int operator *(const Point &b)const{
        return x*b.x+y*b.y;
    }
    void input(){
        scanf("%d%d",&x,&y);
    }
};
int dis2(Point a,Point b){
    return (a-b)*(a-b);
}
Point List[MAXN];
int Stack[MAXN],top;
bool _cmp(Point p1,Point p2){
    int tmp=(p1-List[0])^(p2-List[0]);
    if(tmp>0) return true;
    else if(tmp==0&&dis2(p1,List[0])<=dis2(p2,List[0])) return true;
    else return false;
}
void Graham(int n){
    Point p0;
    int k=0;
    p0=List[0];
    for(int i=1;i<n;i++){
        if(p0.y>List[i].y||(p0.y==List[i].y&&p0.x>List[i].x)){
            p0=List[i];
            k=i;
        }
    }
    swap(List[k],List[0]);
    sort(List+1,List+n,_cmp);
    if(n==1){
        top=1;
        Stack[0]=0;
        return;
    }
    if(n==2){
        top=2;
        Stack[0]=0;
        Stack[1]=1;
        return;
    }
    Stack[0]=0;
    Stack[1]=1;
    top=2;
    for(int i=2;i<n;i++){
        while(top>1&&((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0)
            top--;
        Stack[top++]=i;
    }
    return;
}
int rotating_calipers(Point p[],int n){
    int ans=0;
    Point v;
    int cur=1;
    for(int i=0;i<n;i++){
        v=p[i]-p[(i+1)%n];
        while((v^(p[(cur+1)%n]-p[cur]))<0)
            cur=(cur+1)%n;
        ans=max(ans,max(dis2(p[i],p[cur]),dis2(p[(i+1)%n],p[(cur+1)%n])));
    }
    return ans;
}
Point p[MAXN];
int main() {
#ifdef LOCAL
    freopen("data.in","r",stdin);
#endif // LOCAL
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++) List[i].input();
        Graham(n);
        for(int i=0;i<top;i++) p[i]=List[Stack[i]];
        printf("%d
",rotating_calipers(p,top));
    }
    return 0;
}

 

以上是关于POJ - 2187 Beauty Contest(最远点对)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2187 Beauty Contest 水平序GrahamScan法

poj 2187 Beauty Contest——旋转卡壳

POJ - 2187 Beauty Contest(最远点对)

POJ2187 Beauty Contest (旋转卡壳算法 求直径)

POJ2187 Beauty Contest(旋转卡壳)

模板 旋转卡壳 poj2187