• 极角排序那些事


    极角排序用于想按照某个旋转方向来按顺序访问某些点的时候

    当然要根据不同的题目要求实现不同的排序

    但是有一些通用的技巧,在这里写下吧

    先看看这个我实验用的代码(叉积那部分是摘抄的所以有点乱见谅

     1 #include<bits/stdc++.h>
     2 #define x first
     3 #define y second
     4 #define N 100005
     5 using namespace std;
     6 int n;
     7 pair<double,double>p[N];
     8 bool cmp(pair<double,double> A,pair<double,double> B){
     9     if(atan2(A.y,A.x)!=atan2(B.y,B.x))
    10         return atan2(A.y,A.x)<atan2(B.y,B.x);
    11     else return abs(A.x)<abs(B.x);
    12 }
    13 //*************************
    14 double cross(double x1,double y1,double x2,double y2)
    15 {
    16     return (x1*y2-x2*y1);
    17 }
    18 double compare(pair<double,double> a,pair<double,double> b,pair<double,double> c)//¼ÆË㼫½Ç
    19 {
    20     return cross((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
    21 }
    22 bool cmp2(pair<double,double> a,pair<double,double> b) 
    23 {
    24     pair<double,double> c;//Ô­µã
    25     c.x = 0;
    26     c.y = 0;
    27     if(compare(c,a,b)==0)//¼ÆËã²æ»ý£¬º¯ÊýÔÚÉÏÃæÓнéÉÜ£¬Èç¹û²æ»ýÏàµÈ£¬°´ÕÕX´ÓСµ½´óÅÅÐò
    28         return a.x<b.x;
    29     else return compare(c,a,b)>0;
    30 }
    31 //*************************
    32 int main(){
    33     scanf("%d",&n);
    34     for(int i=1;i<=n;i++){
    35         scanf("%lf%lf",&p[i].x,&p[i].y);
    36     }
    37     sort(p+1,p+1+n,cmp);//cmp2
    38     cout<<"here you are"<<endl;
    39     for(int i=1;i<=n;i++)
    40     cout<<p[i].x<<" "<<p[i].y<<endl;
    41 }
    42 /*
    43 12
    44 99 -7
    45 1 0
    46 3 2
    47 6 4
    48 0 7
    49 0 -22
    50 -9 20
    51 0 0
    52 -100 1
    53 -2 0
    54 -1 0
    55 -4 -4
    56 */
    57 /*
    58 5
    59 6 4
    60 0 7
    61 0 0
    62 1 0
    63 3 2
    64 */

    首先是atan2函数

    这个东西要给他点的y,x,注意是先y哦,他会返回一个弧度,排完之后这坨点应该是这个顺序:

    第三象限,y轴负半轴,第四象限,原点,x轴正半轴,第一象限,y轴正半轴,第二象限,x轴负半轴

    用来排所有点还是很方便很的,但是缺点是精度丢失,有可能会WA

    你也可以使用叉乘

    叉积天然正负与逆顺有关的特性非常好利用,而且精度也很良好

    唯一的问题是如果排的点有两个象限及以上就会非常蛋疼,排的都不知道是啥

    上面那个就只能排第二个

    第一组点集就算了吧,还会根据读入顺序不同出来的也不同。。。

    两种方法各有利弊,请酌情选择吧

  • 相关阅读:
    SDUSTOJ 1466
    UVa
    51Nod
    UVa
    easyui-启用禁用方法
    设置系统时间
    移除/添加属性
    .net生成二维码图片
    Mysql数据库误删恢复
    js 加减乘除运算
  • 原文地址:https://www.cnblogs.com/2017SSY/p/11082770.html
Copyright © 2020-2023  润新知