poj 1696 Space Ant(叉积的性质,做极角排序)

//以下为原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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值