poj 2187 Beauty Contest 题解(凸包模板+旋转卡壳)

来源:互联网 发布:徐千雅最新网络歌曲 编辑:程序博客网 时间:2024/05/22 13:36

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

题意:求所给出的点中,距离最远的点对的距离

#include<stdio.h>#include<algorithm>#include<math.h>#define MAX 50009using namespace std;struct Node{int x;int y;}p[MAX];int top,s[MAX],n;int cross(struct Node a, struct Node b, struct Node c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}int dis(struct Node a, struct Node b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}bool cmp(struct Node a, struct Node b){//返回false的时候交换 ,逆时针排序 int ans=cross(p[0],a,b);if(ans>0||(ans==0&&dis(p[0],a)<dis(p[0],b))){return true;}return false;}/**int cmp1(const void *a,const void *b) //逆时针排序 返回正数要交换,逆时针排序 {    struct Node *c=(struct Node *)a;    struct Node *d=(struct Node *)b;    int k=cross(p[0],*c,*d);    if(k<0) return 1;    else if(k==0 && (dis(p[0],*c)>=dis(p[0],*d)))         return 1;    else return -1;}**/void graham(){s[0]=0;s[1]=1;top=1;int i;for(i=2;i<n;i++){//求上凸壳 while(top>0&&cross(p[s[top-1]],p[s[top]],p[i])<=0){//这样构造的凸包是逆时针的。top--;//如果是 cross(p[s[top]],p[s[top-1]],p[i]),则是按照顺时针构造的凸包(提前十逆时针给所有点排序的),//那么就必须要用这种上凸壳和下凸壳才能构造出完整的凸包,同时最后s[top]==s[0];也就是凸包的起始点出现在了开始和结尾//这样就为后面的旋转卡壳做了准备,旋转卡壳中就不需要做s[++top]=s[0],这一步了。 }s[++top]=i;}int tmp=top;s[++top]=n-2;for(i=n-3;i>=0;i--){//求下凸壳 while(top>tmp&&cross(p[s[top-1]],p[s[top]],p[i])<=0){top--;}s[++top]=i; }}int RC(){//由于是上下凸壳构造的凸包,则不用做s[++top]=s[0]; int q=1;int ans=0;for(int i=0;i<top;i++){while(abs(cross(p[s[i+1]],p[s[i]],p[s[(q+1)%top]]))>abs(cross(p[s[i+1]],p[s[i]],p[s[q]]))){q=(q+1)%top;}ans=max(ans,max(dis(p[s[i]],p[s[q]]),dis(p[s[i+1]],p[s[q+1]])));}return ans;}int main(){int zero=0;while(~scanf("%d",&n)){for(int i=0;i<n;i++){scanf("%d %d",&p[i].x,&p[i].y);}zero=0;for(int i=0;i<n;i++){if(p[zero].y>p[i].y||(p[zero].y==p[i].y&&p[zero].x>p[i].x)) zero=i;}struct Node tmp;tmp=p[0];p[0]=p[zero];p[zero]=tmp;sort(p+1,p+n,cmp);//qsort(p+1,n-1,sizeof(p[0]),cmp1); graham();printf("%d\n",RC());}return 0;}/**70 00 11 11 02 20 22 0 205521 -4185157 3291439 98684812 -29034993 5723-9349 8008-9267 -4272-4861 -95006270 -49627394 -1099-4349 8442-1944 -4915147 -5526-2062 4624-7775 8187156 7746-9646 -96861038 -2855-9818 -4150594 5175100 010000 01 1002 1999999 1009998 199100 -900200 -17999800 -17999900 -900**/


#include<stdio.h>#include<algorithm>#include<math.h>#define MAX 50009using namespace std;struct Node{int x;int y;}p[MAX];int top,s[MAX],n;int cross(struct Node a, struct Node b, struct Node c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}int dis(struct Node a, struct Node b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}bool cmp(struct Node a, struct Node b){//返回false的时候交换 int ans=cross(p[0],a,b);if(ans>0||(ans==0&&dis(p[0],a)<dis(p[0],b))){return true;}return false;}void graham(){s[0]=0;s[1]=1;top=1;int i;for(i=2;i<n;i++){while(top>0&&cross(p[s[top-1]],p[s[top]],p[i])<=0){//sort排序也要和这个一样(比如同为顺时针或者同为逆时针),才能构造凸包 top--;}s[++top]=i;}}int RC(){int q=1;int ans=0;s[++top]=0;//上面的求凸包的方式,这个地方一定要给栈顶加上起始点 for(int i=0;i<top;i++){while(abs(cross(p[s[(i+1)%top]],p[s[i]],p[s[(q+1)%top]]))>abs(cross(p[s[(i+1)%top]],p[s[i]],p[s[q]]))){q=(q+1)%top;}ans=max(ans,max(dis(p[s[i]],p[s[q]]),dis(p[s[(i+1)%top]],p[s[(q+1)%top]])));}return ans;}int main(){int zero=0;while(~scanf("%d",&n)){for(int i=0;i<n;i++){scanf("%d %d",&p[i].x,&p[i].y);}zero=0;for(int i=0;i<n;i++){if(p[zero].y>p[i].y||(p[zero].y==p[i].y&&p[zero].x>p[i].x)) zero=i;}struct Node tmp;tmp=p[0];p[0]=p[zero];p[zero]=tmp;sort(p+1,p+n,cmp);graham();printf("%d\n",RC());}return 0;}


0 0
原创粉丝点击