• Space Ant POJ


    Space Ant  POJ - 1696

    题目链接:https://vjudge.net/problem/POJ-1696

    题意:给你很多点的坐标,一只蚂蚁要最多可以经过多少点,且每经过一个点的路线不能和之前经过的路线重复相交,该蚂蚁只能直线走或者向左边走

    思路:找到纵坐标最小(纵坐标相等横坐标满足最小)的点作为起始点,对剩下的点相当于极角排序,利用叉积,求出最外面的凸包相对于该起始点的下一点,然后将改点作为剩余点的起始点,再对剩下的点进行极角排序,得出最外凸包过程中的下一点,重复操作,故肯定能把所有的点走完

    // 
    // Created by HJYL on 2020/1/17.
    //
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const double eps=1e8;
    int dcmp(double x)
    {
        if(fabs(x)<eps)
            return 0;
        return x<0?-1:1;
    }
    struct Point{
        double x,y;
        int id;
        Point(){}
        Point(int id,double x,double y):id(id),x(x),y(y){}
    }initial;//以当前点来求最外凸包
    
    typedef Point Vector;
    
    Vector operator-(Point A,Point B)
    {
        return Vector(-1,A.x-B.x,A.y-B.y);
    }
    //叉积
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    
    double Len(Point A,Point B)
    {
        return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
    }
    
    //极角排序
    bool cmp(const Point& A,const Point& B)
    {
        double t=Cross(A-initial,B-initial);
        if(t>0)//叉积大于0,B在A的左边,A在外凸包上
            return true;
        else if(t<0)
            return false;
        else
            return Len(A,initial)<Len(B,initial);//极角相同采用最近的点
    
    }
    
    const int maxn=100;
    int main()
    {
        Point p[maxn];
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d",&n);
            initial=Point(0,1e10,1e10);//初始化一开始的点
            for(int i=0;i<n;i++)
            {
                scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);
                if(initial.y>p[i].y||(initial.y==p[i].y&&initial.x>p[i].x))//找出最下面且最左边的点
                    initial=Point(p[i].id,p[i].x,p[i].y);//更新原始点
            }
            swap(p[0],p[initial.id-1]);//将点集的第一点为原始要操作的点
            int serial[maxn];
            int pos=0;
            serial[pos++]=initial.id;//输出的序号数组,第一个就是原始操作的点
            for(int i=1;i<n;i++)
            {
                sort(p+i,p+n,cmp);//对剩下的点进行极角排序
                initial=p[i];//更新原始点
                serial[pos++]=p[i].id;
            }
            printf("%d ",n);
            for(int i=0;i<pos;i++)
                printf("%d ",serial[i]);
            printf("
    ");
        }
        return 0;
    }

     

  • 相关阅读:
    js简单地发送一个请求
    浏览器缓存知识归纳
    文本选择问题: css & js
    闭包和重写函数 返回IE浏览器版本号
    新项目启动 考虑问题
    Angular 单元格合并
    pointer-events 使用场景
    移动开发 新建空白页面
    CSS Tip
    垂直居中方法
  • 原文地址:https://www.cnblogs.com/Vampire6/p/12206606.html
Copyright © 2020-2023  润新知