题目链接:POJ 1696 Space Ant
在纸上画画能发现不管给出的是怎么的一些点,都是可以按照一定方式并且遵循规则走完的。
这个方式就是卷包裹了,和一般的卷包裹法的区别是这个题是不走重复点的,所以需要加一个vis数组。而卷包裹是需要走到起点的,所以要允许走重复点。
关于卷包裹法这个博客写的很好:http://www.cnblogs.com/Booble/archive/2011/02/28/1967179.html
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const double eps = 1e-10;
const int MAX_N = 50 + 10;
struct Point
{
double x, y;
Point(double x=0, double y=0):x(x),y(y) { }
};
typedef Point Vector;
Vector operator + (const Vector& A, const Vector& B)
{
return Vector(A.x+B.x, A.y+B.y);
}
Vector operator - (const Point& A, const Point& B)
{
return Vector(A.x-B.x, A.y-B.y);
}
Vector operator * (const Vector& A, double p)
{
return Vector(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);
}
int dcmp(double x)
{
if(fabs(x) < eps)
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 Cross(const Vector& A, const Vector& B)
{
return A.x*B.y - A.y*B.x;
}
double Dot(const Vector& A, const Vector& B)
{
return A.x*B.x + A.y*B.y;
}
double Length(const Vector& A)
{
return sqrt(Dot(A, A));
}
struct Path
{
Point p;
int index;
};
Path path[MAX_N];
int vis[MAX_N], _output[MAX_N];
int main()
{
//freopen("in.txt", "r", stdin);
int T, n;
scanf("%d", &T);
while(T--)
{
memset(vis, 0, sizeof(vis));
scanf("%d", &n);
int _minX = 1000, _minY = 1000, _start, _size = 0, _beg, _end;
for(int i = 0; i < n; i++)
{
scanf("%d%lf%lf", &path[i].index, &path[i].p.x, &path[i].p.y);
if(_minY > path[i].p.y || (dcmp(_minY - path[i].p.y) == 0 && _minX > path[i].p.x))
{
_start = i;
_minY = path[i].p.y;
_minX = path[i].p.x;
}
}
_output[_size++] = path[_start].index;
vis[path[_start].index] = 1;
_beg = _start;
bool flag = true;
while(_size < n)
{
flag = true;
for(int i = 0; i < n; i++)
{
if(vis[path[i].index])
continue;
if(flag)
{
_end = i;
flag = false;
continue;
}
if(dcmp(Cross(path[i].p - path[_beg].p, path[_end].p - path[_beg].p)) > 0)
_end = i;
else if(dcmp(Cross(path[i].p - path[_beg].p, path[_end].p - path[_beg].p)) == 0)
{
if(dcmp(Length(path[i].p - path[_beg].p) - Length(path[_end].p - path[_beg].p)) < 0)
_end = i;
}
}
_output[_size++] = path[_end].index;
_beg = _end;
vis[path[_end].index] = 1;
}
printf("%d ", _size);
for(int i = 0; i < _size - 1; i++)
printf("%d ", _output[i]);
printf("%d\n", _output[_size - 1]);
}
return 0;
}