POJ 1696 Space Ant 卷包裹法
Space Ant
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3316 Accepted: 2118 Description
The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists traced down an ant-like creature in the planet Y1999 and called it M11. It has only one eye on the left side of its head and just three feet all on the right side of its body and suffers from three walking limitations:
- It can not turn right due to its special body structure.
- It leaves a red path while walking.
- It hates to pass over a previously red colored path, and never does that.
The pictures transmitted by the Discovery space ship depicts that plants in the Y1999 grow in special points on the planet. Analysis of several thousands of the pictures have resulted in discovering a magic coordinate system governing the grow points of the plants. In this coordinate system with x and y axes, no two plants share the same x or y.
An M11 needs to eat exactly one plant in each day to stay alive. When it eats one plant, it remains there for the rest of the day with no move. Next day, it looks for another plant to go there and eat it. If it can not reach any other plant it dies by the end of the day. Notice that it can reach a plant in any distance.
The problem is to find a path for an M11 to let it live longest.
Input is a set of (x, y) coordinates of plants. Suppose A with the coordinates (xA, yA) is the plant with the least y-coordinate. M11 starts from point (0,yA) heading towards plant A. Notice that the solution path should not cross itself and all of the turns should be counter-clockwise. Also note that the solution may visit more than two plants located on a same straight line.Input
The first line of the input is M, the number of test cases to be solved (1 <= M <= 10). For each test case, the first line is N, the number of plants in that test case (1 <= N <= 50), followed by N lines for each plant data. Each plant data consists of three integers: the first number is the unique plant index (1..N), followed by two positive integers x and y representing the coordinates of the plant. Plants are sorted by the increasing order on their indices in the input file. Suppose that the values of coordinates are at most 100.Output
Output should have one separate line for the solution of each test case. A solution is the number of plants on the solution path, followed by the indices of visiting plants in the path in the order of their visits.Sample Input
2
10
1 4 5
2 9 8
3 5 9
4 1 7
5 3 2
6 6 3
7 10 10
8 8 1
9 2 4
10 7 6
14
1 6 11
2 11 9
3 8 7
4 12 8
5 9 20
6 3 2
7 1 6
8 2 13
9 15 1
10 14 17
11 13 19
12 5 18
13 7 3
14 10 16Sample Output
10 8 7 3 4 9 5 6 2 1 10
14 9 10 11 5 12 8 7 6 13 4 14 1 3 2Source
/*************************************************************************
> File Name: poj_1696.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年04月14日 星期二 16时41分10秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#define EPS 1e-8
using namespace std;
const int maxn = ;
struct point{
double x, y;
int num;//定点序号
};
point p[maxn];
bool vis[maxn];//标记是否已经取到
int ans[maxn];//保存取的顺序
int m, n;
int k;
bool cmp(const point p1, const point p2)//排序比较函数,这个题其实不用排序,找到y最小的点那个就行了
{
return (p1.y == p2.y && p1.x < p2.x || p1.y < p2.y);
}
int sgn(double x)
{
if (fabs(x) < EPS)
return ;
return x < ? - : ;
}
double get_direction(point p1, point p2, point p3)//p1p3在p1p2的左侧的时候小于0
{
return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y);
}
double get_distance(point p1, point p2)//两点之间的距离
{
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
void jarvis()//卷包裹法
{
memset(vis, false, sizeof(vis));
vis[] = vis[] = true;//其中p[0]是构造出来的,由题意可知,第一个点在y轴上
int optimal, cur = ;//optimal保存最优的(最靠外的)那个点,cur是当前点
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
if (!vis[j])
{
optimal = j; break;//从待选泽的点中随便找一个点让optimal等于它,因为下面要和其他的点比较
}
}
for (int j = ; j <= n; j++)
{
if (!vis[j] && optimal != j && sgn(get_direction(p[cur], p[j], p[optimal])) < )//这里是没有共线的情况,如果有共线的话必须严格的判断
{
optimal = j;
}
}
vis[optimal] = true;
cur = optimal;
ans[k++] = p[optimal].num;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d", &m);
while (m--)
{
k = ;
memset(ans, , sizeof(ans));
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d %lf %lf", &p[i].num, &p[i].x, &p[i].y);
sort(p + , p + n + , cmp);//排序
p[].num = ; p[].x = ; p[].y = p[].y;//构造第一个点
ans[k++] = p[].num;
jarvis();
printf("%d ", n);
for (int i = ; i < k; i++)
printf("%d ", ans[i]);
puts("");
} return ;
}
其中上面有个步骤是没有严格的判断是否共线的问题,不过也能AC,可能数据比较少把,下面给出严格的判断共线问题的代码
void jarvis()
{
memset(vis, false, sizeof(vis));
vis[] = vis[] = true;
int optimal, cur = ;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
if (!vis[j])
{
optimal = j; break;
}
}
for (int j = ; j <= n; j++)
{
if (!vis[j] && optimal != j && sgn(get_direction(p[cur], p[j], p[optimal])) <= )
{
if (sgn(get_direction(p[cur], p[j], p[optimal])) == )//如果共线
{
if (get_distance(p[cur], p[j]) < get_distance(p[cur], p[optimal]))//判断距离小的点是哪个
optimal = j;
}
else
optimal = j;
}
}
vis[optimal] = true;
cur = optimal;
ans[k++] = p[optimal].num;
}
}
POJ 1696 Space Ant 卷包裹法的更多相关文章
- poj 1696 Space Ant (极角排序)
链接:http://poj.org/problem?id=1696 Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- 简单几何(凸包) POJ 1696 Space Ant
题目传送门 题意:一个蚂蚁一直往左边走,问最多能走多少步,且输出路径 分析:就是凸包的变形题,凸包性质,所有点都能走.从左下角开始走,不停排序.有点纠结,自己的凸包不能AC.待理解透凸包再来写.. 好 ...
- 2018.07.04 POJ 1696 Space Ant(凸包卷包裹)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Description The most exciting space discovery occu ...
- POJ 1696 Space Ant(极角排序)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2489 Accepted: 1567 Descrip ...
- poj 1696 Space Ant(模拟+叉积)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3840 Accepted: 2397 Descrip ...
- POJ 1696 Space Ant(点积的应用)
Space Ant 大意:有一仅仅蚂蚁,每次都仅仅向当前方向的左边走,问蚂蚁走遍全部的点的顺序输出.開始的点是纵坐标最小的那个点,開始的方向是開始点的x轴正方向. 思路:从開始点開始,每次找剩下的点中 ...
- poj 1696:Space Ant(计算几何,凸包变种,极角排序)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2876 Accepted: 1839 Descrip ...
- POJ 1696 - Space Ant 凸包的变形
Technorati Tags: POJ,计算几何,凸包 初学计算几何,引入polygon后的第一个挑战--凸包 此题可用凸包算法做,只要把压入凸包的点从原集合中排除即可,最终形成图形为螺旋线. 关于 ...
- POJ 1696 Space Ant(凸包变形)
Description The most exciting space discovery occurred at the end of the 20th century. In 1999, scie ...
随机推荐
- .NET 4.0 使用 asyn await
.NET 4.0 也可以使用asyn await 使用nuget 搜索await即可发现微软官方包,安装导项目就可以使用了. 参考:http://stackoverflow.com/questio ...
- GNU FORK PTHREAD SIGNALS
Linux程序设计入门 - fork, pthread, and signals 在UNIX程序设计中,学会fork及signal的运用,算是相当基本的功夫. fork()及signal经常运用在da ...
- Hybrid UI framework shootout: Ionic vs. Famo.us vs. F7 vs. OnsenUI
1 Introduction In the past 2 years I’ve been working intensively on mobile applications, mostly hybr ...
- 【Web Service】WSDL文档
WSDL文档仅仅是一个简单的XML文档. 它包含一系列描述某个web service的定义. WSDL WSDL 是基于 XML 的语言,用于描述 Web services 以及如何访问它们. WSD ...
- Color the Fence
Codeforces Round #202 (Div. 2) B:http://codeforces.com/problemset/problem/349/B 题意:给你一些颜料,然后你可以用这些颜料 ...
- ios入门之c语言篇——基本函数——2——判断闰年
2.闰年判断 参数返回值解析: 参数: a:int,年份: 返回值: 1:闰年: 0:非闰年: int leapyear(int a) { ==) { ; } ==) { ; } ==) { ; } ...
- ios入门之c语言篇——基本函数——1——随机数生成
1.随机数函数 参数返回值解析: 参数: a:int,数字范围最小值: b:int,数字范围最大值: 返回值: 1:闰年: 0:非闰年: 备注: a-b的绝对值不能超过int的最大值(65535); ...
- GNU工具链学习笔记
GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...
- 将汉字转化为拼音,正则表达式和得到汉字的Unicode编码
一:上图,不清楚的看代码注解,很详细了 二:具体代码 窗体代码 using System; using System.Collections.Generic; using System.Compone ...
- VMware连不上网解决
在VMware里安装了ubuntu,但是某一天打开它,ubuntu忽然不能上网了,于是百度了好几个方法,最后是这样解决的: 额...现在连接的是无线,前两天出问题的时候连接的是有线,在Internet ...