POJ 1696 Space Ant 贪心

来源:互联网 发布:php魔方加密在线解密 编辑:程序博客网 时间:2024/05/16 16:59



每次选择向左偏移角度最小的下一个点即可。或者说左边点最多的点。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cstdlib>#include <cmath>#include <map>#include <sstream>#include <queue>#include <vector>#define MAXN 100005#define MAXM 211111#define eps 1e-8#define INF 500000001using namespace std;inline int dblcmp(double d){    if(fabs(d) < eps) return 0;    return d > eps ? 1 : -1;}struct point{    double x, y;    point(){}    point(double _x, double _y): x(_x), y(_y) {}    void input()    {        scanf("%lf%lf", &x, &y);    }    bool operator ==(point a)const    {        return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;    }    point sub(point p)    {        return point(x - p.x, y - p.y);    }    double dot(point p)    {        return x * p.x + y * p.y;    }    double det(point p)    {        return x * p.y - y * p.x;    }    double distance(point p)    {        return hypot(x - p.x, y - p.y);    }}p[555];int vis[555];int n;vector<int>ans;int getcount(point a, int id){    int cnt = 0;    for(int i = 1; i <= n; i++)    {        if(vis[i] || id == i) continue;        point tmp = p[i].sub(p[id]);        if(dblcmp(a.det(tmp)) >= 0) cnt++;    }    return cnt;}void disable(point a, int id){    for(int i = 1; i <= n; i++)    {        if(vis[i]) continue;        point tmp = p[i].sub(p[id]);        if(dblcmp(a.det(tmp)) < 0) vis[i] = 1;    }}int main(){    int T;    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);        p[0] = point(0, 0);        int pre = 0, now = -1, id;        for(int i = 1; i <= n; i++)        {            scanf("%d", &id); p[i].input();            if(now == -1 || p[i].y < p[now].y) now = i;        }        memset(vis, 0, sizeof(vis));        ans.clear();        ans.push_back(now);        vis[now] = 1;        while(true)        {            int nxt = -1, cnt = 0;            for(int i = 1; i <= n; i++)                if(!vis[i])                {                    point x = p[i].sub(p[now]);                    int num = getcount(x, i);                    if(num >= cnt)                        nxt = i, cnt = num;                }            if(nxt == -1) break;            vis[nxt] = 1;            point tmp = p[nxt].sub(p[now]);            disable(tmp, nxt);            ans.push_back(nxt);            pre = now;            now = nxt;        }        printf("%d", ans.size());        for(int i = 0; i < ans.size(); i++) printf(" %d", ans[i]);        printf("\n");    }    return 0;}