[POJ 2187]Beauty Contest:旋转卡壳

来源:互联网 发布:骑马与砍杀捏脸数据女 编辑:程序博客网 时间:2024/05/16 11:59

点击这里查看原题

旋转卡壳模板题,建议看这里的讲解

旋转卡壳的代码只比凸包多几行,非常好写。

/*User:SmallLanguage:C++Problem No.:2187*/#include<stdio.h>#include<iostream>#include<iomanip>#include<string.h>#include<algorithm>#include<queue>#include<stack>#include<math.h>#define ll long long#define inf 999999999using namespace std;const int M=5e4+5;int n,s[M],tp,k;int ans;struct no{    int x,y;}p[M];void init(){    memset(s,0,sizeof(s));    tp=k=0;}int dis(no a,no b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int cross(no a,no b,no c){    no u=(no){b.x-a.x,b.y-a.y},v=(no){c.x-a.x,c.y-a.y};    return u.x*v.y-u.y*v.x;}bool cmp(no a,no b){    int tmp=cross(p[0],a,b);    if(tmp==0) return dis(p[0],a)<dis(p[0],b);    return tmp>0;}void graham(){    for(int i=0;i<n;i++){        while(tp>1&&cross(p[s[tp-2]],p[s[tp-1]],p[i])<=0) tp--;        s[tp++]=i;    }}void rc(){    int i=0,j=1;    s[tp]=s[0];    ans=dis(p[s[i]],p[s[i+1]]);    for(i=0;i<tp;i++){        while(abs(cross(p[s[i+1]],p[s[j+1]],p[s[i]]))>abs(cross(p[s[i+1]],p[s[j]],p[s[i]]))) j=(j+1)%tp;//找到距离p[s[i]],p[s[i+1]]两点连线最远的点j         ans=max(ans,max(dis(p[s[i]],p[s[j]]),dis(p[s[i+1]],p[s[j+1]])));//既要算dis(p[s[i]],p[s[j]])也要算dis(p[s[i+1]],p[s[j+1]]),因为可能会出现两线平行的情况     }}void solve(){    init();    for(int i=0;i<n;i++){        cin>>p[i].x>>p[i].y;        if(p[i].x<p[k].x||(p[i].x==p[k].x&&p[i].y<p[k].y)) k=i;    }    swap(p[k],p[0]);    sort(p+1,p+n,cmp);    graham();    rc();    cout<<ans<<endl;}int main(){    freopen("data.in","r",stdin);//    ios::sync_with_stdio(false);    while(cin>>n&&n) solve();    return 0;}