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; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com