//以下为原blog搬迁过来的内容
【题目大意】:有一只M11,它每天必须靠走路到某些点吃植物维系生命,但是由于身体条件的限制,它不能向右转,也不能走交叉的路,问你怎么走能吃到最多的路径。(起点是(0,y)。y表示最下做左端的点的纵坐标)
【解题思路】:一拿到题目,几乎立刻就想dfs一遍。之后想想,在练习计算几何嘛。这个时候利用了叉积的性质。取一个点出来,跟当前所在的点构成线段,再取另外一个点,求三点的叉积,如果叉积>eps则意味着有点在第一次取出的点的右方,那么显然要走右边的点先。另外如果发现叉积等于0,那么我们肯定要选择一个离当前点最近的点去走。
所以,最后还是yy了一个sort出来。然后提交,测几组数据后a了再去翻题解。发现,貌似我yy出了所谓的极角排序。
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
using namespace std;
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
struct Point
{
int num;
double x, y;
Point() {}
Point(int aa,double a, double b)
{
num=aa,x = a, y = b;
}
}point[1000];
int i;
double p,q;
inline int sig(double k) {
return k < -eps ? -1 : k > eps;
}
inline double det(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
inline double xmult(Point o, Point a, Point b)
{
return det(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y);
}
inline double getDist(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool cmp(const Point &a,const Point &b)
{
int k;
k=xmult(a,b,point[i-1]);
if (sig(k)>0) return true;
else
{
if (sig(k)==0)
{
double dis1,dis2;
dis1=getDist(a,point[i-1]);
dis2=getDist(b,point[i-1]);
return dis1<dis2;
}
else return false;
}
}
int main()
{
int T,n,m;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int j=0; j<=n-1; j++)
{
scanf("%d%lf%lf",&m,&p,&q);
point[j]=Point(m,p,q);
if (point[j].y<point[0].y)
swap(point[j],point[0]);
}
printf("%d %d",n,point[0].num);
int k=2;
for (i=1; i<n; i++)
{
sort(point+i,point+n,cmp);
//if (i!=n-1)
printf(" %d",point[i].num);
}
printf("\n");
}
return 0;
}