典型的旋转卡壳,有两种方法:
一:先求凸包,然后一一枚举凸包上的每两个点
二:裸的旋转卡壳。
顺便推荐一个讲旋转卡壳的好地方~ http://www.cnblogs.com/Booble/archive/2011/04/03/2004865.html
//凸包
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 120000;
const double eps = 1e-6;
const double pi=3.141592654;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
struct point{ double x,y; };
point c[MAX];
double disp2p(point a,point b)
{
return ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y );
}
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向
{
return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
bool cmp(point a,point b) // 排序
{
double len = crossProduct(c[0],a,b);
if( dd(len,0.0) )
return xy(disp2p(c[0],a),disp2p(c[0],b));
return xy(len,0.0);
}
int stk[MAX];
int top;
double sum = 0.0;
void Graham(int n)
{
int tmp = 0;
for(int i=1; i<n; i++)//
if( xy(c[i].x,c[tmp].x) || dd(c[i].x,c[tmp].x) && xy(c[i].y,c[tmp].y) )
tmp = i;
swap(c[0],c[tmp]);
sort(c+1,c+n,cmp);
stk[0] = 0; stk[1] = 1;
top = 1;
for(int i=2; i<n; i++)
{
while( xyd( crossProduct(c[stk[top]],c[stk[top-1]],c[i]), 0.0 ) && top >= 1 )
top--;
stk[++top] = i;
}
//cout<<"top "<<top<<endl;
}
int main()
{
int n;
double len;
while(cin>>n&& n )
{
for(int i=0;i<n;i++)
cin>>c[i].x>>c[i].y;
Graham(n);
double nowlen;
len=0.0;
for(int i=0; i<=top; i++)
for(int j=0;j<=top;j++)
if(j!=i)
{
nowlen=disp2p(c[stk[i]],c[stk[j]]);
if(nowlen>len) len=nowlen;
}
/*
想不明白,凸包上不相邻两点的 距离肯定大于相邻两点,但是 WA 。如果一一枚举凸包上点 ,A 。
for(int i=0; i<top-1; i++)
for(int j=+2;j<=top;j++)
{
nowlen=disp2p(c[stk[i]],c[stk[j]]);
if(nowlen>len) len=nowlen;
}
*/
printf("%.0lf\n",len);
}
return 0;
}
//卡壳
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 120000;
const double eps = 1e-6;
const double pi=3.141592654;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
struct point{ double x,y; };
point c[MAX];
double disp2p(point a,point b)
{
return ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y );
}
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向
{
return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
bool cmp(point a,point b) // 排序
{
double len = crossProduct(c[0],a,b);
if( dd(len,0.0) )
return xy(disp2p(c[0],a),disp2p(c[0],b));
return xy(len,0.0);
}
int stk[MAX];
int top;
double sum = 0.0;
void Graham(int n)
{
int tmp = 0;
for(int i=1; i<n; i++)//
if( xy(c[i].x,c[tmp].x) || dd(c[i].x,c[tmp].x) && xy(c[i].y,c[tmp].y) )
tmp = i;
swap(c[0],c[tmp]);
sort(c+1,c+n,cmp);
stk[0] = 0; stk[1] = 1;
top = 1;
for(int i=2; i<n; i++)
{
while( xyd( crossProduct(c[stk[top]],c[stk[top-1]],c[i]), 0.0 ) && top >= 1 )
top--;
stk[++top] = i;
}
//cout<<"top "<<top<<endl;
}
double Rotating_calipers(int stk[],int n)
{
stk[ n] = stk[0];
int q = 1;
double ans = 0.0;
for(int i=0; i<n; i++)
{
while( xy(fabs(crossProduct(c[stk[i]],c[stk[i+1]],c[stk[q]])),fabs(crossProduct(c[stk[i]],c[stk[i+1]],c[stk[q+1]]))) )
q = (q+1)%n;
ans = max(ans,disp2p(c[stk[i]],c[stk[q]]));
}
return ans;
}
int main()
{
int n;
double len;
while(cin>>n&& n )
{
for(int i=0;i<n;i++)
cin>>c[i].x>>c[i].y;
Graham(n);
len=Rotating_calipers(stk,top+1); //注意:是 top+1
printf("%.0lf\n",len);
}
return 0;
}