題目:http://poj.org/problem?id=2187
今天終於耐下心來學習凸包和旋轉卡殼了,以poj的經典例題2187爲例,學習主要參考了以下兩篇博文:
http://www.cnblogs.com/Booble/archive/2011/04/03/2004865.html
http://blog.csdn.net/x314542916/article/details/7949096
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX 50005
int N;
struct Point{
int x, y;
} points[MAX];
Point ch[MAX]; int top;
int cross(const Point& o, const Point& a, const Point& b)
{
return (a.x-o.x)*(b.y-o.y) - (b.x-o.x)*(a.y-o.y);
}
int dist2(const Point& a, const Point& b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
struct Compare
{
Point o;
bool operator()(const Point& a, const Point& b)const{
//return true if a should be in front b
//that is oa smaller polar angle, that is ob is on the anticlockwise order of oa
//so that oa x ob > 0
int r = cross(o, a, b);
if(r != 0) return r > 0;
return dist2(o, a) < dist2(o, b);
}
};
bool input()
{
if(scanf("%d", &N) != 1) return false;
for(int i = 0; i < N; ++i)
scanf("%d%d", &points[i].x, &points[i].y);
return true;
}
int findLeftDown()
{
int k = 0;
for(int i = 1; i < N; ++i){
if(points[i].x < points[k].x || points[i].x == points[k].x && points[i].y < points[k].y){
k = i;
}
}
return k;
}
void grahamScan()
{
//step 1: sort up by polar angle
int o = findLeftDown();
Compare comparator;
comparator.o = points[o];
swap(points[o], points[0]);
sort(points+1, points+N, comparator);
//step 2: scan every point check if it disobey convex rule
ch[0] = points[0];
ch[1] = points[1];
ch[2] = points[2];
top = 2;
for(int i = 3; i < N; ++i){
while(top && cross(ch[top-1], ch[top], points[i]) <= 0) --top;
ch[++top] = points[i];
}
//now ch[0] ~ ch[top] are the points that compose of the convex hull
}
int rotateCalipers(Point* ch, int n)
{
int q = 1, ans = 0;
ch[n] = ch[0];
for(int p = 0; p < n; ++p){
while(cross(ch[p], ch[p+1], ch[q+1]) > cross(ch[p], ch[p+1], ch[q]))
q = (q+1) % n;
ans = max(ans, max(dist2(ch[p], ch[q]), dist2(ch[p+1], ch[q+1])));
}
return ans;
}
int main()
{
while(input()){
grahamScan();
printf("%d\n", rotateCalipers(ch, top+1));
}
return 0;
}