题目链接:poj 1696
题意:是给你n个点,一只蚂蚁要从y坐标最小的那个点开始,逆时针依次走过所有的点,要求不能走之前走过的点,蚂蚁只能逆时针(向左转)前进。
题解:极角排序一下,每次出发都取左偏量最小的跑。
///极角排序,每次出发都取左偏量最小的点
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct point
{
double x,y;
int index;
point(){}
point(double _x,double _y){
x=_x;y=_y;
}
}node[100];
point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,double p) { return point(a.x*p,a.y*p);}
point operator / (point a,double p){ return point(a.x/p,a.y/p);}
bool operator < (const point &a,const point &b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double esp=1e-8;
int dcmp(double x){
if(fabs(x)<esp) return 0;
else return x<0?-1:1;
}
bool operator ==(const point &a,const point &b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(point A,point B) { return A.x*B.x+A.y*B.y;}///2,点积,即是|a||b|*cos<a,b>,可用来判断角度的范围
double Length(point A) {return sqrt(Dot(A,A));} ///两点之间的距离
double Cross(point a,point b) { return a.x*b.y-a.y*b.x;}
int pos; ///极角排序时的根据
bool cmp(point a,point b){
double item=Cross(a-node[pos],b-node[pos]);
if(dcmp(item)==0) return Length(a-node[pos])<Length(b-node[pos]);
else if(dcmp(item)>0) return true;///如果叉积大于0,说明pos到a点的极角大于b
else return false;
}
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%lf%lf",&node[i].index,&node[i].x,&node[i].y);
if(node[i].y<node[0].y||(node[i].y==node[0].y&&node[i].x<node[0].x))
swap(node[0],node[i]);
}
pos=0;
for(int i=1;i<n;i++)
{
sort(node+i,node+n,cmp);
pos++;
}
printf("%d ",n);
for(int i=0;i<n;i++)
printf("%d ",node[i].index);
puts("");
}
return 0;
}