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; }