/* 每次新选点时都要将上一个方向延长,作为新的x轴,然后将上一个点作为原点O,给剩下的点进行一次极角排序 极角排序:普通的极角排序要判断象限,但是本题不用判象限, 因为不难证明,所有剩下的点相对新坐标系,都在一,二象限内 如果还有点在第三,四象限,那么这些点应该被先访问到:所以cmp里只要进行一次叉积判断 */ #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 200 typedef double db; const db eps=1e-6; const db pi=acos(-1); int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;} int cmp(db k1,db k2){return sign(k1-k2);} struct point{ db x,y; int id; point(){} point(db x,db y):x(x),y(y){} point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};} point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} point operator * (db k1) const{return (point){x*k1,y*k1};} point operator / (db k1) const{return (point){x/k1,y/k1};} }O,p[N]; db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;} int n; bool comp(point a,point b){ return sign(cross(a-O,b-O))>0; } int main(){ int t;cin>>t; while(t--){ cin>>n; for(int i=1;i<=n;i++) scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y); O.y=O.x=1e16; for(int i=1;i<=n;i++){ if(O.y>p[i].y)O=p[i]; else if(O.y==p[i].y && O.x>p[i].x)O=p[i]; } swap(p[1],p[O.id]); for(int i=2;i<=n;i++){ sort(p+i,p+1+n,comp); O=p[i]; } cout<<n; for(int i=1;i<=n;i++)cout<<" "<<p[i].id; puts(""); } }