zoukankan      html  css  js  c++  java
  • POJ 1696 Space Ant --枚举,模拟,贪心,几何

    题意: 有很多点,从最右下角的点开始走起,初始方向水平向右,然后以后每步只能向左边走,问最多能走多少个点。

    解法: 贪心的搞的话,肯定每次选左边的与它夹角最小的点,然后走过去。 然后就是相当于模拟地去选点,然后计数,然后走过去。这题就这么搞定了。

    我这里用了set和vector。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <set>
    #define Mod 1000000007
    #define pi acos(-1.0)
    #define eps 1e-8
    using namespace std;
    
    int nonsense;
    struct Point{
        double x,y;
        Point(double x=0, double y=0):x(x),y(y) {}
        void input() { scanf("%d%lf%lf",&nonsense,&x,&y); }
    };
    typedef Point Vector;
    int dcmp(double x) {
        if(x < -eps) return -1;
        if(x > eps) return 1;
        return 0;
    }
    template <class T> T sqr(T x) { return x * x;}
    Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
    Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
    Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
    Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
    bool operator < (const Point& a, const Point& b) { return a.y < b.y || (a.y == b.y && a.x < b.x); }
    bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
    bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
    bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
    double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
    double Length(Vector A) { return sqrt(Dot(A, A)); }
    double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
    double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
    
    //data segment
    Point p[55];
    set<int> sk;
    vector<int> ans;
    //data ends
    
    int main()
    {
        int t,n,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            sk.clear(), ans.clear();
            for(i=1;i<=n;i++) p[i].input(), sk.insert(i);
            int mintag = 1;
            double miny = p[1].y, minx = p[1].x;
            for(i=2;i<=n;i++)
            {
                if(p[i].y < miny)
                    mintag = i, miny = p[i].y, minx = p[i].x;
                else if(p[i].y == miny && p[i].x < minx)
                    mintag = i, minx = p[i].x;
            }
            Vector now = Vector(1,0);
            Point pnow = p[mintag];
            ans.push_back(mintag);
            sk.erase(mintag);
            set<int>::iterator it;
            while(1)
            {
                double Mini = Mod;
                int tag;
                for(it=sk.begin();it!=sk.end();it++)
                {
                    Point A = p[*it]-pnow;
                    double ang = Angle(now,A);
                    if(ang < Mini)
                        Mini = ang, tag = *it;
                }
                if(Mini >= Mod) break;
                now = p[tag]-pnow;
                pnow = p[tag];
                ans.push_back(tag);
                sk.erase(tag);
                if(sk.empty()) break;
            }
            printf("%d",ans.size());
            for(i=0;i<ans.size();i++)
                printf(" %d",ans[i]);
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    吴裕雄--天生自然 Zookeeper学习笔记--ZooKeeper 数据模型 znode 结构详解
    吴裕雄--天生自然 Zookeeper学习笔记--Zookeeper Java 客户端搭建
    吴裕雄--天生自然 Zookeeper学习笔记--Zookeeper linux 服务端集群搭建步骤
    吴裕雄--天生自然 Zookeeper学习笔记--Zookeeper 安装配置
    吴裕雄--天生自然 Zookeeper学习笔记--ZooKeeper
    吴裕雄--天生自然 使用python的pandas_alive包生成动态图
    程序规范示例
    迭代器Iteration
    斐波拉契数列(Fibonacci)--用生成器生成数列
    Python中装饰器的用法
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4160556.html
Copyright © 2011-2022 走看看