题目大意: 很简单的意思,蚂蚁只能向左转,求最多走的点数和路径
想法: 每个点都能遍历到,先弄清楚这点,然后发现规律是对于每次到达的一个点,下个点都是对与当前点极角最小的。O(n^2)时间过,0ms.....
角度排序用cross叉积就可以了
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))
using namespace std;
const double EPS = 1e-8;
inline int sign(double a) {
return a < -EPS ? -1 : a > EPS;
}
struct Point {
double x, y;
int id;
Point() {
}
Point(double _x, double _y) :
x(_x), y(_y) {
}
Point operator+(const Point&p) const {
return Point(x + p.x, y + p.y);
}
Point operator-(const Point&p) const {
return Point(x - p.x, y - p.y);
}
Point operator*(double d) const {
return Point(x * d, y * d);
}
Point operator/(double d) const {
return Point(x / d, y / d);
}
bool operator<(const Point&p) const {
int c = sign(x - p.x);
if (c)
return c == -1;
return sign(y - p.y) == -1;
}
double dot(const Point&p) const {
return x * p.x + y * p.y;
}
double det(const Point&p) const {
return x * p.y - y * p.x;
}
double alpha() const {
return atan2(y, x);
}
double distTo(const Point&p) const {
double dx = x - p.x, dy = y - p.y;
return hypot(dx, dy);
}
double alphaTo(const Point&p) const {
double dx = x - p.x, dy = y - p.y;
return atan2(dy, dx);
}
void read() {
scanf("%d%lf%lf", &id,&x, &y);
}
double abs() {
return hypot(x, y);
}
double abs2() {
return x * x + y * y;
}
void write() {
cout << "(" << x << "," << y << ")" << endl;
}
};
Point temp;
bool cmp(Point a,Point b)
{
return a.y<b.y;
}
bool cmp_angel(Point a,Point b)
{
int t=crossOp(temp,a,b);
if(t<0) return false; //说明a的再b的顺时针方向上,说明极角小
else if(t>0) return true;
else
{
int da=temp.distTo(a);
int db=temp.distTo(b);
if(da<=db)return false ;
else return true;
}
}
Point p[51];
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
p[i].read();
sort(p+1,p+1+n,cmp);
temp=p[1];
cout<<n<<" ";
cout<<p[1].id<<" ";
for(int i=2;i<=n;i++)
{
sort(p+i,p+1+n,cmp_angel);
temp=p[i];
cout<<p[i].id<<" ";
}
cout<<endl;
}
}