题目中指定了ant爬行时的几种规则,从中我们可以知道ant是按照当前所处位置,对其他的plant进行极角排序后,选择角度最小过去,重复,一直到走到最后一个plant。
sort一发就可以了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
const double eps=1e-8;
const int maxn=50+5;
using namespace std;
int N; //点的个数
int sgn(double x){
if(fabs(x)<eps)
return 0;
if(x>0)
return 1;
if(x<0)
return -1;
}
struct point{
int index; // the index of point
int x,y;
point() {}
point(int _x,int _y){
x=_x;
y=_y;
}
};
typedef point vector;
vector operator + (vector A,vector B){
return point(A.x+B.x,A.y+B.y);
}
vector operator - (point A,point B){
return point(A.x-B.x,A.y-B.y);
}
int operator ^ (vector A,vector B){
return A.x*B.y-A.y*B.x;
}
int operator * (vector A,vector B){
return A.x*B.x+A.y*B.y;
}
double dis(point a,point b)
{
return hypot(a.x-b.x,a.y-b.y);
}
point p[maxn];
int q[maxn];
int pos,cnt;
bool cmp(point a,point b) //极角排序函数
{
int d=(a-p[pos])^(b-p[pos]);
if(d==0&&sgn(dis(a,p[pos])-dis(b,p[pos])) < 0 || d>0)
return true; //共线时取较近的点
return false;
}
void init(){ //找出起始点
p[0].y=p[1].y;
for(int i=1;i<=N;i++)
if(p[i].y<p[0].y)
p[0]=point(0,p[i].y);
}
void solve(){
cnt=0;pos=0;
for(int i=0;i<N;i++){
sort(p+pos+1,p+N+1,cmp);
pos++;
q[pos]=p[pos].index;
cnt++;
}
}
int main(){
//freopen("input.txt","r",stdin);
int M;
cin>>M;
while(M--){
memset(p,0,sizeof(p));
cin>>N;
for(int i=1;i<=N;i++){
int index,x,y;
scanf("%d%d%d",&index,&x,&y);
p[index]=point(x,y);
p[index].index=index;
}
init();
solve();
/*for(int i=1;i<=N;i++)
printf("(%d,%d)\n",p[i].x,p[i].y);*/
cout<<cnt;
for(int i=1;i<=cnt;i++)
printf(" %d",q[i]);
cout<<endl;
}
return 0;
}