现在的位置: 首页 > 综合 > 正文

POJ 1696 Space Ant 贪心

2014年02月16日 ⁄ 综合 ⁄ 共 1597字 ⁄ 字号 评论关闭

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

#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 500000001
using 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;
}

抱歉!评论已关闭.