坐标上有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;
}