2018杭电多校第三场1007(凸包,极角排序)

Posted ldudxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018杭电多校第三场1007(凸包,极角排序)相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
using namespace std;
typedef const long long ll;
struct node
{
    int x,y;
    int pos;
}plane[200020],tubao[200020],stt;
int top;
int n;
long long multi(node a,node b,node c)
{
    ll mianji=1ll*(a.x-c.x)*(b.y-c.y)-1ll*(a.y-c.y)*(b.x-c.x);//面积公式判断正负值
    return mianji;
}
bool cmp(node a,node b)
{
    if(a.x==b.x&&a.y==b.y)
        return a.pos>b.pos;//重复点,字典序大的排在前(此处如果将字典序小的排在前,则WA,原因未知)
    if(!multi(stt,b,a))//两个点与原点的连线斜率相等,即三点共线
        return pow(a.x-stt.x,2)+pow(a.y-stt.y,2)<pow(b.x-stt.x,2)+pow(b.y-stt.y,2);
        //和原点距离近的排在前
    return multi(stt,b,a)>0;//multi为正说明联接凸包的顺序a在b之前(a在b下面如果纵坐标相等a横坐标更小)
}
void graham()
{
    tubao[1]=plane[1];
    tubao[2]=plane[2];
    top=3;
    for(int i=3;i<=n;i++)
    {
        while(top>2&&multi(tubao[top-2],plane[i],tubao[top-1])<=0)
        {
            if(multi(tubao[top-2],plane[i],tubao[top-1])<0||plane[i].pos<tubao[top-1].pos)//处理字典序问题
                //该点应在栈中第二点之前联接凸包或者和第二点重合然而字典序靠前
                top--;
            else
                break;
        }
        tubao[top++]=plane[i];//用栈模拟联接凸包顺序
    }
    for(int i=1;i<top;i++)
    {
        printf("%d%c",tubao[i].pos,i==top-1?‘ ‘:‘ ‘);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int x,y;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            plane[i].x=x;
            plane[i].y=y;
            plane[i].pos=i;
        }
        stt=plane[1];
        sort(plane+2,plane+1+n,cmp);//起点不参与排序
        graham();
    }
    return 0;
}

//坐标排序待补



































































以上是关于2018杭电多校第三场1007(凸包,极角排序)的主要内容,如果未能解决你的问题,请参考以下文章

2018 Multi-University Training Contest 3 杭电多校第三场

2020杭电多校第三场题解

2020杭电多校第三场

杭电多校第三场 A Ascending Rating

[2020杭电多校第三场]1008 Triangle Collision

2021杭电多校第三场-Road Discount-wqs二分+最小生成树