【题意】
求一个只向左转的路径,使得经过最多的点,但每个点不能重复走。
【题解】
水题,叉积应用,极角排序。
【代码】
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=55;
struct point
{
int x,y,id;
}p[maxn],b[maxn],ans[maxn];
bool v[maxn];
int n,tot,cnt,i,cc;
int xmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
double dist(point p1,point p2)
{
return sqrt(double((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
bool cmp1(point a,point b)
{
return a.y<b.y || a.y==b.y && a.x<b.x;
}
bool cmp2(point a,point b)
{
return xmult(a,b,ans[tot])>0 || xmult(a,b,ans[tot])==0 && dist(a,ans[tot])<dist(b,ans[tot]);
}
int main()
{
freopen("pin.txt","r",stdin);
freopen("pou.txt","w",stdout);
cin >> cc;
while (cc--)
{
memset(v,0,sizeof(v));
cin >> n;
for (i=0;i<n;i++)
cin >> p[i].id >> p[i].x >> p[i].y;
sort(p,p+n,cmp1);
tot=1;
ans[tot]=p[0];
ans[0].x=0;ans[0].y=p[0].y;
v[p[0].id]=true;
while (1)
{
cnt=0;
for (i=0;i<n;i++)
if (!v[p[i].id] && xmult(p[i],ans[tot],ans[tot-1])<=0)
b[cnt++]=p[i];
if (cnt==0) break;
sort(b,b+cnt,cmp2);
ans[++tot]=b[0];
v[b[0].id]=true;
}
cout << tot;
for (i=1;i<=tot;i++)
cout << " " << ans[i].id;
cout << endl;
}
return 0;
}