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;
}

 

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