题意:蚂蚁从最小的的点开始走,每一次只能往右走,走的路线不能交叉,怎样才能试经过的路线最长。走完所有的点,经过的路线最长。
思路:找到最下方的点,然后枚举其他所有未访问的点。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const double INF = 1e20;
const double EPS = 1e-6;
struct cvector{
double x,y;
cvector(double a,double b){x=a,y=b;}
cvector(){}
};
cvector operator-(cvector a,cvector b){
return cvector(a.x-b.x,a.y-b.y);
}
cvector operator+(cvector a,cvector b){
return cvector(a.x+b.x,a.y+b.y);
}
cvector operator*(double a,cvector b){
return cvector(a*b.x,a*b.y);
}
double operator*(cvector a,cvector b){
return a.x*b.x+a.y*b.y;
}
double operator^(cvector a,cvector b){
return a.x*b.y-b.x*a.y;
}
double length(double t){return t>0?t:-t;}
double length(cvector t){return sqrt(t*t);}
struct cpoint{
double x,y;
cpoint(double a,double b){x=a,y=b;}
cpoint(){}
};
cvector operator-(cpoint a,cpoint b)
{
return cvector(a.x-b.x,a.y-b.y);
}
double dist(cpoint a,cpoint b){return length(b-a);}
struct cline{
cpoint a,b;
};
const int N = 59;
struct nod{
cpoint a;
int i;
bool operator<(const nod t) const
{
return a.y<t.a.y;
}
} re[N];
int n,ans[N],visit[N];
cpoint A,B;
double oor(int i)
{
return ((B-A)*(re[i].a-B))/length(re[i].a-B);
}
int main()
{
freopen("in.txt","r",stdin);
int cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
int t = 0;double c = INF;
int cnt=0;
memset(visit,false,sizeof(visit));
for(int i=1;i<=n;i++)
{
scanf("%d%lf%lf",&re[i].i,&re[i].a.x,&re[i].a.y);
if(re[i].a.y<c)
t=i,c=re[i].a.y;
}
A.x=0,A.y=re[t].a.y;
B=re[t].a;
ans[cnt++]=re[t].i;
visit[t] = true;
while(cnt<n)
{
c=-INF;
for(int i=1;i<=n;i++)
if(!visit[i])
{
double tmp = oor(i);
if(tmp>c)
c= tmp,t=i;
}
visit[t]=true;
A=B;B=re[t].a;
ans[cnt++]=re[t].i;
}
printf("%d",n);
for(int i=0;i<n;i++)
printf(" %d",ans[i]);printf("\n");
}
return 0;
}