zoukankan      html  css  js  c++  java
  • 凸包模板

    题目链接:http://codeforces.com/gym/101484/problem/E

    凸包算法

    1.先找到y坐标最小的点g,然后再让所有的点都减去g.x和g.y,再对它们进行极角排序

    2.排序后的数组为,node[1],node[2],node[3],node[4]......node[n-1],其中node[0]为y坐标最小的点,node[1]和node[n]一定为凸包上的点

    3.将node[0],node[1],node[2],入凸包栈,检查栈顶,也就是node[2],判断向量(node[2]-node[1])与(node[3]-node[2])的叉积,也就是他们是左旋转还是右旋转,如果是右旋转,则node[2]不是凸包上的点,node[2]就出栈

    4.node[3]入栈,重复3和4的过程

     

    极角排序

    根据每个点与原点连线和x轴的夹角排序,如果夹角相同,则按照距离排序,都是从小到大

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=1e5+10;
    struct Node
    {
        ll x,y,fla;
        bool operator <(const Node &a)const
        {
             long double co1=1.0*x/sqrt(x*x+y*y);
             long double co2=1.0*a.x/sqrt(a.x*a.x+a.y*a.y);
             if(a.x*y==a.y*x)//判断夹角是否相同
                return sqrt(x*x+y*y)<sqrt(a.x*a.x+a.y*a.y);
             else
                return co1>co2;
        }
    }node[maxn*2],ans[maxn*2];
    
    ll check(Node &a,Node &b,Node &c)//叉积
    {
       // cout<<a.fla<<" "<<b.fla<<" "<<c.fla<<endl;
        ll x1=b.x-a.x;
        ll y1=b.y-a.y;
        ll x2=c.x-b.x;
        ll y2=c.y-b.y;
        if(x1*y2-x2*y1>=0)return 1;
        else return 0;
    }
    int now;
    int main()
    {
        int n,m;
        ll mix=1e9,miy=1e9,fla;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld %lld",&node[i].x,&node[i].y);
            node[i].fla=i;
            if(node[i].y<=miy)
                miy=node[i].y,fla=i,mix=node[i].x;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%lld %lld",&node[i+n].x,&node[i+n].y);
            node[i+n].fla=i+n;
            if(node[i+n].y<=miy)
                miy=node[i+n].y,fla=i+n,mix=node[i+n].x;
        }
        for(int i=1;i<=m+n;i++)
            node[i].x-=mix,node[i].y-=miy;
        node[0]=node[fla];
        for(int i=fla+1;i<=n+m;i++)
            node[i-1]=node[i];
        sort(node+1,node+n+m);
        ans[0]=node[0];
        ans[1]=node[1];
        ans[2]=node[2];
        now=2;
        for(int i=3;i<n+m;i++)
        {
            while(check(ans[now-1],ans[now],node[i])==0)
                now--;
            now++;
            ans[now]=node[i];
        }
        int nn=n,mm=m;
    
        for(int i=0;i<=now;i++)
        {
            if(ans[i].fla<=n)nn--;
            else mm--;
        }
        if((nn==n&&mm==0)||(mm==m&&nn==0))cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    指针变量的值和指针变量地址
    定时备份docker容器中mysql的数据
    sql server表外键查询
    Go语言strings包基本操作
    centos安装字体库处理中文乱码
    codeforces 1610D
    汽车配件生产加工企业管理软件出售生产加工刹车盘、刹车鼓、刹车蹄、刹车片等企业通用
    关于document.onmousemove报错Invalid or unexpected token问题
    SilverLight支持的DataTable可以直接绑定
    我的工作我的状态
  • 原文地址:https://www.cnblogs.com/carcar/p/9850390.html
Copyright © 2011-2022 走看看