POJ-2187(旋轉卡殼)

題目: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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章