思路:
答案数量一定会是输入点的数量,因为点的横纵坐标都是唯一的,大概就能知道都能选上
主要就是极角排序,以当前点为准点,判断两个点哪个在左边或右边,直接利用叉积就可以
bool cmp(P a,P b){ //比较函数,x[l]为准点,a在b的右边
return (a.x-x[l].x)*(b.y-x[l].y)-(b.x-x[l].x)*(a.y-x[l].y)>EXP;
}
每选一个数就进行一次极角排序,选择排序后的第一个点,继续排序即可。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
#define fo(a,b) for(int i=a;i<=b;i++)
#define inf 0x3f3f3f3f
#define dou double
#define EXP 1e-8
#define ll long long
#define M 10005
int t,n,l;
int ans[M];
struct P{
double x,y;
int id;
P(double x=0,double y=0):x(x),y(y){}
}x[M];
bool cmp(P a,P b){ //比较函数,x[l]为准点,a在b的右边
return (a.x-x[l].x)*(b.y-x[l].y)-(b.x-x[l].x)*(a.y-x[l].y)>EXP;
}
int main()
{
cin>>t;
while(t--){
cin>>n;
int a,b,c,id,miny=inf;
fo(1,n){
cin>>a>>b>>c;
x[a].x=b;x[a].y=c;x[a].id=i;
if(c<miny) id=a,miny=c;
}
l=1;
swap(x[id],x[l]);
while(l<=n){
ans[l]=id;
sort(x+l+1,x+n+1,cmp); //极角排序
l++;id=x[l].id;
}
cout<<n<<" ";
fo(1,n-1) cout<<ans[i]<<" ";
cout<<ans[n]<<endl;
}
return 0;
}