poj 1696 (计算几何基础)

poj 1696 Space Ant

链接:http://poj.org/problem?id=1696

题意:在坐标轴上,给定n个点的 id 以及点的坐标(xi, yi),让你以最底端点开始,从右依次找出最外围的的点,形成一个螺旋状的图像。图形见题目例题,输出他们的 id。

思路:先找出最下面的点,然后依次为“据点”,对其他点进行极角排序,取出第一个点,以此点为“据点”,对其他未选择的点极角排序,选出排序后第一个点,……, 依此类推,取得 n 个点。复杂度(n^2*log(n))。

 

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define op operator
#define cp const P&
#define cn const
using namespace std;

struct P{
    int x, y, id;
    void in() {scanf("%d %d %d", &id, &x, &y);}
    P(int a=0, int b=0) : x(a), y(b) {}
    P op-(cp a)cn {return P(x-a.x, y-a.y);}
    bool op<(cp a)cn {return (x==a.x) ? y<a.y : x<a.x;}
    int op^(P a) {return x*a.y - y*a.x;}
    int cross(P a, P b) {return (a-*this) ^ (b-*this);}
    int op*(P a) {return x*a.x + y*a.y;}
    int dot(P a, P b) {return (a-*this) * (b-*this);}
    int dis(P a) {return (x-a.x)*(x-a.x) + (y-a.y)*(y-a.y);}
}p[50], q;

inline bool cmp(P a, P b) {
    P v1 = a-q, v2 = b-q;
    if((v1^v2) > 0) return true;
    return (v1^v2) == 0 && (q.dis(a)-q.dis(b))<0;
}

int ks[50], c;

int main()
{
    freopen("in.in", "r", stdin);

    int t, n, i, j;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        for(i = 0; i < n; ++i) {
            p[i].in();
            if(p[0].y > p[i].y) swap(p[0], p[i]);
        }
        c = 0;
        ks[c++] = p[0].id;
        q = p[0];
        sort(p+1, p+n, cmp);
        for(i = 1; i < n; ++i) {
            ks[c++] = p[i].id;
            q = p[i];
            sort(p+i+1, p+n, cmp);
        }
        printf("%d", n);
        for(i = 0; i < n; ++i) printf(" %d", ks[i]);
        puts("");
    }
    return 0;
}

 

 

原文地址:https://www.cnblogs.com/Duahanlang/p/3689400.html