#include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<stdlib.h> #include<cmath> #include<queue> #include<algorithm> using namespace std; #define rd(x) scanf("%d",&x) #define rdd(x,y) scanf("%d%d",&x,&y) #define rddd(x,y,z) scanf("%d%d%d",&x,&y,&z) #define rds(s) scanf("%s",s) #define rep(i,n) for(int i=0;i<n;i++) #define LL long long const int N = 100; const int M=5e5+10; const int inf=1e9; const double eps=1e-5; const int MOD=1e9+7; int n,m; struct Point{ double x,y; int id; Point(){ } Point(double _x,double _y){ x=_x;y=_y; } bool operator < (const Point&a) const{ if(y==a.y) return x<a.x; return y<a.y; } }; Point p1,p2,p3,p4; struct Seg{ Point s,e; Seg(){} Seg(Point _s,Point _e){ s=_s; e=_e; } Seg(double x,double y,double xx,double yy){ s.x=x;s.y=y; e.x=xx;e.y=yy; } }; double cross(Point a,Point b,Point c){ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } double dist(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int sgn(double x){ return x<-eps?-1:x<eps?0:1;} int inter(Seg a,Seg b){ Point p1,p2,p3,p4; p1=a.s;p2=a.e; p3=b.s;p4=b.e; if (!(min(p1.x,p2.x)<=max(p3.x,p4.x) && min(p3.x,p4.x)<=max(p1.x,p2.x) && min(p1.y,p2.y)<=max(p3.y,p4.y) && min(p3.y,p4.y)<=max(p1.y,p2.y))) return -1;/*不相交*/ int d1= sgn(cross(p1,p2,p3)); int d2=sgn(cross(p1,p2,p4)); int d3=sgn(cross(p3,p4,p1)); int d4=sgn(cross(p3,p4,p2)); if(d1==0 && d2==0) return 0;/*部分重合*/ if(d1*d2==0 && d3*d4==0) return 1;/*端点重合*/ if(d1*d2==0 || d3*d4==0) return 2;/*一端点在另一线段非端点的点上*/ if(d1*d2<0 && d3*d4<0) return 3;/*线段相交*/ else return -1; } Seg seg[100]; Point point[100]; bool vis[100]; int ans[100]; int tot=0; int pn,sn; int main() { #ifndef ONLINE_JUDGE freopen("aaa","r",stdin); #endif int T; rd(T); while(T--){ rd(n); int mi=1; Point p0; for(int i=1;i<=n;i++){ scanf("%d%lf%lf",&point[i].id,&point[i].x,&point[i].y); } sort(point+1,point+1+n); p0=point[1]; for(int i=1;i<=n;i++) vis[i]=false; tot=0; ans[tot++]=p0.id; vis[p0.id]=true; Point p1,p2; for(int i=2;i<=n;i++){ int j; for(j=1;j<=n;j++) if(!vis[point[j].id]){p1=point[j];break;} for(j++;j<=n;j++) { if(!vis[point[j].id] && sgn(cross(p0,p1,point[j]))<0) { p1=point[j]; } } vis[p1.id]=true; ans[tot++]=p1.id; p0=p1; } printf("%d ",n); for(int i=0;i<tot;i++) printf("%d%c",ans[i],i==tot-1?'\n':' '); } return 0; }