POJ 1696 Space Ant 点积计算夹角

题意:

一只特别的蚂蚁,只能直走或者左转。在一个平面上,有很多株植物,这只蚂蚁每天需要进食一株,这只蚂蚁从起点为(0,miny)的点开始出发。求最多能活多少天

分析:

肯定是可以吃到所有植物的,以当前方向无限延长成直线,可以剩余的植物都在直线的左边。所以就是求上一个位置到当前位置与下一个位置与当前位置的夹角,并且使夹角最大。

cos(0~pi)是单调递减的,夹角越大,cos值越小。所以我用点积来计算。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define eps 1e-8
#define INF 1e9
using namespace std;

const int maxn=100;

typedef struct Point
{
    double x,y;
    Point() {};
    Point(double xx,double yy)
    {
        x=xx;
        y=yy;
    }
} Vector;

double crs_prdct(Vector a,Vector b)
{
    return a.x*b.y-b.x*a.y;
}

double dot_prdct(Vector a,Vector b)
{
    return a.x*b.x+a.y*b.y;
}

Vector operator - (Point a,Point b)
{
    return Vector(a.x-b.x,a.y-b.y);
}

double dist(Vector v)
{
    return sqrt(v.x*v.x+v.y*v.y);
}

double dist(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

Point pot[maxn];
bool vis[maxn];

int main()
{
//    freopen("in.txt","r",stdin);
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int idx;
        double x,y;
        int minp=1;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%lf%lf",&idx,&x,&y);
            pot[i]=Point(x,y);
            if(y==pot[minp].y) minp=x<pot[minp].x? i:minp;
            if(y<pot[minp].y) minp=i;
        }
        pot[0]=Point(0,pot[minp].y);
        memset(vis,0,sizeof(vis));
        int last=0,now=minp;
        printf("%d %d",n,now);
        vis[now]=1;
        for(int i=2; i<=n; i++)
        {
            int next;
            Vector now_v=Vector(pot[last]-pot[now]);
            double cosA=INF;
            for(int j=1; j<=n; j++)
            {
                if(vis[j]) continue;
                Vector next_v=Vector(pot[j]-pot[now]);
                double cosB=dot_prdct(now_v,next_v)/dist(now_v)/dist(next_v);
                if(cosB<cosA)
                {
                    cosA=cosB;
                    next=j;
                }
            }
            printf(" %d",next);
            vis[next]=1;
            last=now;
            now=next;
        }
        puts("");
    }
    return 0;
}

 

posted @ 2017-07-21 10:06  Pacify  阅读(239)  评论(0编辑  收藏  举报