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

本文讨论了一种M11生物如何通过优化路线选择来最大化获取植物资源的效率,利用叉积和极角排序算法实现路径选择,确保生物在特定约束条件下达到最佳生存状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目大意】:有一只M11,它每天必须靠走路到某些点吃植物维系生命,但是由于身体条件的限制,它不能向右转,也不能走交叉的路,问你怎么走能吃到最多的路径。(起点是(0,y)。y表示最下做左端的点的纵坐标)

 

【解题思路】:一拿到题目,几乎立刻就想dfs一遍。之后想想,在练习计算几何嘛。这个时候利用了叉积的性质。取一个点出来,跟当前所在的点构成线段,再取另外一个点,求三点的叉积,如果叉积>eps则意味着有点在第一次取出的点的右方,那么显然要走右边的点先。另外如果发现叉积等于0,那么我们肯定要选择一个离当前点最近的点去走。

所以,最后还是yy了一个sort出来。然后提交,测几组数据后a了再去翻题解。发现,貌似我yy出了所谓的极角排序。

 

【代码】:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

#define eps 1e-8

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;
}


 

【运行结果】:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值