• 巨人与鬼


    随便写了写不知道对不对……

    2333333

    主要:考虑y坐标最小的点,y轴坐标相同则考虑最左边的点。则其他所有点的极角都在(0,Pi]之间,对极角从小到大排序。不妨设那个点为巨人

    则如果第一个点是鬼则完成配对,如果并不是鬼则,按照极角顺序从小到大检查一直到巨人数目和鬼的数目一致,然后进行下一轮递归……

    ////啊啊啊啊,极角排序……!

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <stack>
    #include <cctype>
    #include <string>
    #include <malloc.h>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    const int INF = 0xffffff;
    const double esp = 10e-8;
    const double Pi = 4 * atan(1.0);
    const int Maxn = 2000+10;
    const long long mod =  2147483647;
    const int dr[] = {1,0,-1,0,-1,1,-1,1};
    const int dc[] = {0,1,0,-1,1,-1,-1,1};
    typedef long long LL;
    
    LL gac(LL a,LL b){
        return b?gac(b,a%b):a;
    }
    
    struct guest{
        double x,y,angle;
        int v;
        int num1;
        int num2;
        bool operator < (const guest a)const{
            if(abs(y-a.y) < esp)
                return x < a.x;
            return y < a.y;
        }
    };
    
    bool cmp(const guest a,const guest b){
        return a.angle < b.angle;
    }
    
    double get_angle(guest a,guest b){
        if(abs(a.x - b.x) < esp)
            return atan(0xfffffff);
        double tt = atan((a.y-b.y)/(a.x-b.x));
        if(tt < 0)
            tt += Pi;
        return tt;
    }
    
    guest arr[1000];
    
    void dis(int s,int e){
        if(e-s == 1){
            arr[s].num2 = arr[e].num1;
            arr[e].num2 = arr[s].num1;
            return;
        }
        sort(arr+s,arr+e+1);
        int sum = arr[s].v;
        for(int i = s+1;i <= e;i++){
            arr[i].angle = get_angle(arr[s],arr[i]);
        }
        sort(arr+s+1,arr+e+1,cmp);
        int t = s;
        while(sum){
            sum += arr[++t].v;
        }
        dis(s,t);
        dis(t+1,e);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("inpt.txt","r",stdin);
    #endif
        int n;
        while(~scanf("%d",&n)){
            for(int i = 0;i < n;i++){
                scanf("%d%lf%lf",&arr[i].num1,&arr[i].x,&arr[i].y);
                arr[i].v = 1;
                arr[i].num2 = 0;
            }
            for(int i = n;i < 2*n;i++){
                scanf("%d%lf%lf",&arr[i].num1,&arr[i].x,&arr[i].y);
                arr[i].v = -1;
                arr[i].num2 = 0;
            }
            dis(0,2*n-1);
            for(int i = 0;i < 2*n;i++){
                if(arr[i].v > 0){
                    cout << arr[i].num1 << ' ' << arr[i].num2 << endl;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    svg手写标签
    使用node搭建本地服务器
    window电脑上设置鼠标触屏板的开关
    本地git如何与gitlab连接
    utools中的内网穿透下架,可使用natapp替代。
    移动端rem.js
    扫码登录开发者工具时,提示:调试过程中开发者可通过以下公众号获得你的相关信息。怎么取消这个公众号啊?
    实现图片的延迟加载
    Chrome 中安装 Vue 扩展程序
    VMWare虚拟机Bridged类型网卡ping不通的原因和解决办法
  • 原文地址:https://www.cnblogs.com/hanbinggan/p/4299599.html
Copyright © 2020-2023  润新知