poj 3850 极角排序

题意:让你把n(n<=2000)个点连成一个没有自交的多边形,保证有解。

分析:先取极角大的,再取极角小的,假如有多个极角相同的点怎么办?

那么我们假设最左下角的点为p0, 假如有L,R分别表示极角最小和最大的点与p0所连的直线,

对于这两条直线上假如有多个点,那么L必须从距离p0近的点开始选,R必须从距离p0远的点开始选,其它的

极角相同的一些点的取法  可以从近到远 或 从远到近都是无所谓的。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
int n;
struct point {
	int x, y, id;
	point(int x, int y):x(x), y(y){}
	point(){}
	point operator-(const point &t) const {
		return point(x-t.x, y-t.y);
	}
	void in(int i) {
		scanf("%d%d", &x, &y);
		id = i;
	}
}p[3003];
point cp;

bool cmp(const point &a, const point &b) { //极角序
	double t = a.x*b.y-a.y*b.x;
	return t > 0 || (t==0 && a.x*a.x+a.y*a.y> b.x*b.x+b.y*b.y);
}
int main() {
	int i, j, cas;
	scanf("%d", &cas);
	while(cas--) {
		scanf("%d", &n);
		p[0].in(0);
		for(i = 1; i < n; i++) {
			p[i].in(i);
			if(p[0].x > p[i].x || (p[0].x == p[i].x && p[0].y > p[i].y) )
				swap(p[0], p[i]);
		}
		for(i = n-1; i >= 0; i--) {
                int id = p[i].id;
			p[i] = p[i]-p[0];
			p[i].id = id;
		}
		sort(p+1, p+n, cmp);
		for(i = 1; i < n && p[1].x*p[i].y-p[1].y*p[i].x== 0; i++);
		j = i;
		for(i--;i >= 1; i--)printf("%d ", p[i].id);
		for(i = j; i < n; i++)
			printf("%d ", p[i].id);
		printf("%d\n", p[0].id);
	}
	return 0;
}


你可能感兴趣的:(poj 3850 极角排序)