POJ 1696 Space Ant 【极角排序】

题意:平面上有n个点,一只蚂蚁从最左下角的点出发,只能往逆时针方向走,走过的路线不能交叉,问最多能经过多少个点。

思路:每次都尽量往最外边走,每选取一个点后对剩余的点进行极角排序。(n个点必定能走完,这是凸包的性质决定的)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000; 
const double eps=1e-8;
int sgn(double x){
    if(fabs(x)<eps)    return 0;
    if(x>0)    return 1;
    return -1;
}
struct point{
    double x,y,id;
    point(){}
    point(double x_,double y_){
        x=x_,y=y_;
    }
    point operator -(const point &b)const{
        return point(x-b.x,y-b.y);
    }
    double operator *(const point &b)const{
        return x*b.x+y*b.y;
    }
    double operator ^(const point &b)const{
        return x*b.y-y*b.x;
    }
}po[N];
double dis(point a,point b){
    return sqrt((b-a)*(b-a));
}
int tmp;
int cmp(point a,point b){
    int t=sgn((a-po[tmp])^(b-po[tmp]));
    if(!t)    return dis(po[tmp],a)<dis(po[tmp],b);
    return t>0;
}
int main(){
    int t,n,i;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d%lf%lf",&po[i].id,&po[i].x,&po[i].y);
            if(po[i].y<po[1].y||po[i].y==po[1].y&&po[i].x<po[1].x)
                swap(po[i],po[1]);
        }
        tmp=1;
        for(i=2;i<=n;i++){
            sort(po+i,po+n+1,cmp);
            tmp=i;
        }
        printf("%d",n);
        for(i=1;i<=n;i++)
            printf(" %d",po[i].id);
        puts("");
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/L-King/p/5742558.html