Fork me on GitHub

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

 

posted @ 2014-12-12 22:11  whatbeg  阅读(287)  评论(0编辑  收藏  举报