題意:給定n個點,任意兩點不在一個x軸和y軸上,輸出一條能經過最多點的路線,就下面這圖,每次只能左轉,實際就是外面一圈包進去,
選擇一個最外側點,對剩下點做極角排序,一個個點選下去。能保證每個點都經過。
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<iomanip>
#include<limits.h>
#include<algorithm>
#include<deque>
#include<functional>
#include<iterator>
#include<vector>
#include<list>
#include<map>
#include<memory>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<utility>
using namespace std;
#define mp make_pair
#define ss second
#define ff first
#define pb push_back
template <class T>
void read(T &x)
{
static char ch;
bool neg = false;
while(!isdigit(ch = getchar())) (ch == '-') && (neg = true);
for(x = ch - '0'; isdigit(ch = getchar()); x = x * 10 + ch - '0');
(neg) &&(x = -x);
}
template<class T, class... U> void read(T &head, U &... tail){read(head), read(tail...);}
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 105;
int n,m;
struct P
{
double x, y;
int ind;
} v[maxn];
bool vis[maxn];
double compare(P a, P b, P c)
{
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
P c;
bool cmp(P a, P b)
{
if(compare(c, a, b) == 0)
return a.x < b.x;
else
return compare(c, a, b) > 0;
}
bool cmp1(P a,P b)
{
return a.y<b.y;
}
std::vector<P> w;
std::vector<int> q;
void slove()
{
c=w[0];
q.push_back(c.ind);
vis[c.ind]=true;
w.clear();
for(int i=1;i<n;i++)
{
if(!vis[v[i].ind])
w.push_back(v[i]);
}
if(w.size()==0) return;
sort(w.begin(),w.end(),cmp);
slove();
}
void work()
{
read(n);
q.clear();
w.clear();
memset(vis,false,sizeof vis);
for(int i=0;i<n;i++)
scanf("%d %lf %lf",&v[i].ind,&v[i].x,&v[i].y);
sort(v,v+n,cmp1);
c=v[0];
q.push_back(c.ind);
vis[c.ind]=true;
for(int i=1;i<n;i++)
{
if(!vis[v[i].ind])
w.push_back(v[i]);
}
sort(w.begin(),w.end(),cmp);
slove();
printf("%d",n);
for(int i=0;i<n;i++)
printf(" %d",q[i]);
printf("\n");
}
int main()
{
int T;read(T);while(T--)
//while(~scanf("%d", &n))
work();
}