极角排序+思维——poj1696

时间:2020-02-18
本文章向大家介绍极角排序+思维——poj1696,主要包括极角排序+思维——poj1696使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
/*
每次新选点时都要将上一个方向延长,作为新的x轴,然后将上一个点作为原点O,给剩下的点进行一次极角排序 
极角排序:普通的极角排序要判断象限,但是本题不用判象限,
          因为不难证明,所有剩下的点相对新坐标系,都在一,二象限内
          如果还有点在第三,四象限,那么这些点应该被先访问到:所以cmp里只要进行一次叉积判断
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 200

typedef double db;
const db eps=1e-6;
const db pi=acos(-1);
int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;}
int cmp(db k1,db k2){return sign(k1-k2);} 
struct point{
    db x,y;
    int id;
    point(){}
    point(db x,db y):x(x),y(y){}
    point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    point operator * (db k1) const{return (point){x*k1,y*k1};}
    point operator / (db k1) const{return (point){x/k1,y/k1};}
}O,p[N];
db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}

int n;
bool comp(point a,point b){
    return sign(cross(a-O,b-O))>0;
}

int main(){
    int t;cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++)
            scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);        
        
        O.y=O.x=1e16;
        for(int i=1;i<=n;i++){
            if(O.y>p[i].y)O=p[i];
            else if(O.y==p[i].y && O.x>p[i].x)O=p[i];
        }
        swap(p[1],p[O.id]);
        for(int i=2;i<=n;i++){
            sort(p+i,p+1+n,comp);
            O=p[i];
        }
        cout<<n;
        for(int i=1;i<=n;i++)cout<<" "<<p[i].id;
        puts("");
    }
}
 

原文地址:https://www.cnblogs.com/zsben991126/p/12326479.html