poj 1696 叉积理解

Space Ant

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 3967   Accepted: 2489

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:

  1. It can not turn right due to its special body structure.
  2. It leaves a red path while walking.
  3. 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 16

Sample 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 2
/*
poj 1696 叉积理解

给你n个点,要求从一个点出发,每次只能 左or直走. 求路径
先找出最做下角的点,然后通过叉积排序判断出离当前点需要旋转最小角度可以到达的点
如果两个点在一条直线上面,则选取距离最近的

hhh-2016-05-06 20:40:31
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson  (i<<1)
#define rson  ((i<<1)|1)

using namespace std;
const int  maxn = 40010;
double eps = 1e-8;
int tot;
int n,m;

int sgn(double x)
{
    if(fabs(x) < eps) return 0;
    if(x < 0)
        return -1;
    else
        return 1;
}

struct Point
{
    int id;
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {
        x = _x,y = _y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x-b.x,y-b.y);
    }
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
};

struct Line
{
    Point s,t;
    Line() {}
    Line(Point _s,Point _t)
    {
        s = _s;
        t = _t;
    }
    pair<int,Point> operator &(const Line&b)const
    {
        Point res = s;
        if( sgn((s-t) ^ (b.s-b.t)) == 0)   //通过叉积判断
        {
            if( sgn((s-b.t) ^ (b.s-b.t)) == 0)
                return make_pair(0,res);
            else
                return make_pair(1,res);
        }
        double ta = ((s-b.s)^(b.s-b.t))/((s-t)^(b.s-b.t));
        res.x += (t.x-s.x)*ta;
        res.y += (t.y-s.y)*ta;
        return make_pair(2,res);
    }
};
Point tp;
Point po[maxn];

double dist(Point a,Point b)
{
    return sqrt((a-b)*(a-b));
}

bool cmp(Point a,Point b)
{
    double t = (a-tp)^(b-tp);
    if(sgn(t) == 0)
    {
        return dist(a,tp) < dist(b,tp);
    }
    if(sgn(t) < 0)
        return false;
    else
        return true;
}

int main()
{
    int n,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d", &n);
        tp.x = 10000,tp.y = 10000;
        for(int i = 0; i < n; i++)
        {
            scanf("%d%lf%lf",&po[i].id,&po[i].x,&po[i].y);
            if(po[i].y < tp.y || (po[i].y == tp.y && po[i].x < tp.x))
            {
                tp = po[i];
            }
        }

        for(int i = 0; i < n; i++)
        {
            sort(po+i,po+n,cmp);
            tp = po[i];
        }
        printf("%d ",n);
        for(int i = 0; i < n; i++)
        {
            printf("%d%c",po[i].id, i == n-1 ? ‘\n‘:‘ ‘);
        }
    }
    return 0;
}

  

时间: 2024-10-15 19:25:12

poj 1696 叉积理解的相关文章

POJ 1696 Space Ant(点积的应用)

Space Ant 大意:有一只蚂蚁,每次都只向当前方向的左边走,问蚂蚁走遍所有的点的顺序输出.开始的点是纵坐标最小的那个点,开始的方向是开始点的x轴正方向. 思路:从开始点开始,每次找剩下的点中与当前方向所形成的夹角最小的点,为下一个要走的点(好像就是犄角排序,我不是很会),夹角就是用点积除以两个向量的距离,求一下acos值. 之前一直用叉积做,做了好久样例都没过,发现用错了... 题目挺好的,有助于理解点积与叉积 1 struct Point{ 2 double x, y; 3 int id

POJ 1696

这题是明显的TU包变形. 使用卷包裹法可解,而且是必定可以经过所有点的.直观可知,当经过某点后,相当于把之前的点抹去,求剩下点的TU包,递归下去,也就能把点全部经过了. 于是,只需把经过的点标记一下就可以了. #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cmath> using namespace std; const

poj 1696 Space Ant (极角排序)

链接:http://poj.org/problem?id=1696 Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3077   Accepted: 1965 Description The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists traced down an a

POJ 2752 深刻理解KMP失配指针

思路:刚开始还在想怎么做,虽然以前是理解了失配指针的用处,但是确实不知道失配指针还有如此用处,其实还有很多用处,我用得少了不懂而已. 比如: i   0  1  2  3  4  5   6  7  8  9  10 11 p[i]  A  B R A  C  A  D  A  B  R  A  无 next[i]  0  0  0  0  1  0   1  0  1   2  3   4 next[11]=4这个肯定可以取了,因为这个后缀等于前缀嘛,然后再查询next[next[11]]=n

poj 1696 Space Ant(模拟+叉积)

Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3840   Accepted: 2397 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 Y19

POJ 1696 Space Ant 计算几何 叉积的应用

题目大意:平面内有一些点,我们要通过一些方式来走遍这所有的点,要求一个点只能走一次,只能向左转而不能向右转.求遍历这些点的顺序. 思路:数据范围是可以怎么搞都0ms的(n<=50,case<=100),所以只要有思路就可以了. 只能左转,想想好像有点像凸包啊.但是这个题要遍历所有的点,所以就把已经走过的点删掉,然后像凸包一样的往前走,每次找一个没走过的极角最小的点走,然后把它标记上.最后都走完就全部遍历完了. CODE: #include <cmath> #include <

Poj 1654--Area(叉积)

Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17377   Accepted: 4827 Description You are going to compute the area of a special kind of polygon. One vertex of the polygon is the origin of the orthogonal coordinate system. From thi

poj 1696 Space Ant(极角排序)

Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3661   Accepted: 2281 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 Y19

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 Y19