• 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;
    }
  • 相关阅读:
    一個SQL排序的問題[轉]
    行數據轉換成列數據
    asp页面转化成htm静态页面
    DataGrid 中間隔色的實現
    asp.net里导出excel表方法汇总[轉]
    C#中计算两个时间的差
    asp.net面试的题目
    页面间传输中文的乱码解决方法
    NickLee 多層菜單
    Add an onclick event in the DataGrid for any Column
  • 原文地址:https://www.cnblogs.com/pach/p/7216239.html
Copyright © 2020-2023  润新知