POJ 1696 Space Ant(卷包裹)

这题严格来说不是凸包的题,只是用到了凸包的卷包裹的思想。。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

typedef struct point {
    double x;
    double y;
    int num;
}point;

typedef struct v {
    point start;
    point end;
}v;

double crossProduct(v* v1, v* v2)
{
    v vt1, vt2;
    double result = 0;

    vt1.start.x = 0;
    vt1.start.y = 0;
    vt1.end.x = v1->end.x - v1->start.x;
    vt1.end.y = v1->end.y - v1->start.y;

    vt2.start.x = 0;
    vt2.start.y = 0;
    vt2.end.x = v2->end.x - v2->start.x;
    vt2.end.y = v2->end.y - v2->start.y;

    result = vt1.end.x * vt2.end.y - vt1.end.y * vt2.end.x;
    return result;
}

const int maxn = 55;
const double eps = 1e-8;
point plant[maxn];
int m, n, cnt;
bool vis[maxn];
int path[maxn];

int main()
{
    for(scanf("%d", &m); m--;) {
        int st = 0;
        cnt = 1;
        scanf("%d", &n);
        memset(vis, false, sizeof(vis));
        for(int i = 0; i < n; i++) {
            scanf("%d%lf%lf", &plant[i].num, &plant[i].x, &plant[i].y);
            plant[i].num--;
            if(plant[i].y < plant[st].y) st = i;
        }
        point sp;
        sp.x = 0;
        sp.y = plant[st].y;
        v v0, v1, v2;
        v0.start = sp;
        v0.end = plant[st];
        vis[st] = true;
        path[0] = st;
        bool found;
        do {
            found = false;
            for(int i = 0; i < n; i++) {
                if(vis[i]) continue;
                v1.start = v0.end;
                v1.end = plant[i];
                if(crossProduct(&v0, &v1) >= 0) {
                    if(!found) {
                        found = true;
                        v2 = v1;
                    }
                    else {
                        if(crossProduct(&v1, &v2) > 0 || (fabs(crossProduct(&v1, &v2)) < eps && v1.end.x < v2.end.x))
                            v2 = v1;
                    }
                }
            }
            if(found) {
                v0 = v2;
                vis[v2.end.num] = true;
                path[cnt++] = v2.end.num;
            }
        }while(found);
        printf("%d", cnt);
        for(int i = 0; i < cnt; i++)
            printf(" %d", path[i] + 1);
        printf("\n");
    }

    return 0;
}
/*
100
3
1 1 1
2 2 1
3 3 2
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值