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

 

你可能感兴趣的:(ant)