POJ1696(极角排序)模板题

坐标上有n个点从一个点出发,只能沿直线走,只能逆时针拐弯,求走过每个点的顺序

极角排序博客:几何:极角排序详解

极角排序裸题,但是这题用atan2()很难写,因为atan2()函数返回值是(-π,π)也就是默认按照第四象限到第二象限排序,但是这题是逆时针选点,如果一个点在第二象限,一个在第四象限,那么根据atan2()返回值取小的点会取到第四象限那个点,而实际上应该去第二象限的那个点,所以这题应该用叉乘来排序

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int mx = 105;
const int inf = 0x3f3f3f3f;
const double PI = 3.14159265358979;
const double eps = 1e-8;
int n,pos;

struct Point {
    int x, y, id;
}pt[mx];

double dis(Point a, Point b) {
    return sqrt(1.0*(a.x-b.x)*(a.x-b.x) + 1.0*(a.y-b.y)*(a.y-b.y));
}

double cross(double x1, double y1, double x2, double y2) {
	return x1*y2 - x2*y1;
}

bool cmp(Point a, Point b) {
	double ans = cross(a.x-pt[pos].x,a.y-pt[pos].y,b.x-pt[pos].x,b.y-pt[pos].y);
    if (abs(ans) < eps) return dis(pt[pos],a) < dis(pt[pos],b);
	return ans > 0;
}

bool cmp2(Point a, Point b) {
	
}

int main() {
    int T;
    scanf("%d",&T);

    while (T--) {
        scanf("%d",&n);
        int a, x, y;
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d", &a, &x, &y);
            pt[i].x = x; pt[i].y = y; pt[i].id = a;
            if (y < pt[1].y || (y==pt[1].y && x < pt[1].x)) {
                swap(pt[i].x,pt[1].x);
                swap(pt[i].y,pt[1].y);
                swap(pt[i].id,pt[1].id);
            }
        }
        pos = 1;
        for (int i = 1; i < n; i++) {
            sort(pt+i+1,pt+n+1,cmp);
            pos++;
        }

        printf("%d",n);
        for (int i = 1; i <= n; i++) {
            printf(" %d",pt[i].id);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bpdwn2017/article/details/81585448