首页 > 代码库 > POJ 1696 Space Ant --枚举,模拟,贪心,几何

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-8using 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 segmentPoint p[55];set<int> sk;vector<int> ans;//data endsint 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

 

POJ 1696 Space Ant --枚举,模拟,贪心,几何