• [BZOJ 1913] signaling 信号覆盖


    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1913

    TIP:(注意,这题只能输出6位才能过,7位都不行wtf?) 

    Algorithm:

    此题要从四边形的角度去考虑

    对于原图中能形成的任意一个四边形:

    1、如为凸四边形,明显只有对角和大于180的那两个角形成的三角形的外接圆能包含第4个点

         因此每个凸四边形对答案的贡献为2

    2、如为凹四边形,对答案的贡献只有1:被其他三个角形成的三角形包含的点

    于是最终结果为:

    $frac{num_{凹四边形}+2num_{凸四边形}}{C_n^3(总方案数)}+3$

    由于凹四边形明显比凸四边形更好求

    $frac{num_{凹四边形}+2(C_n^4-num_{凹四边形})}{C_n^3(总方案数)}+3$

    在求凹四边形时,对于每一个点,我们只要求出其被几个三角形包含即可

    但反向求解明显更方便:求多少个三角形不包含x

    其他点以x为原点极角排序,对于每个点计算其ANG~ANG+PI间有多少个点,再统计能生成多少个三角形

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef complex<double> point;
    typedef long long ll;
    
    const int MAXN=5e3;
    const double PI=3.1415926535897384626;
    int n;
    point dat[MAXN];
    double ang[MAXN];
    
    ll res=0;
    
    double C(double a,double b)
    {
        double ret=1;
        for(int i=1;i<=b;i++)
            ret=ret*(a-i+1)/i;
        return ret;
    }
    
    void cal(int pos)
    {
        int len=0;
        for(int i=1;i<=n;i++) //转为极坐标系
            if(i!=pos) ang[++len]=atan2((dat[i]-dat[pos]).real(),(dat[i]-dat[pos]).imag());
        
        sort(ang+1,ang+len+1);
        
        ll llen=len,temp=0;
        for(int i=1;i<=llen;i++)  //首尾相接序列的基本操作
            ang[++len]=ang[i]+2*PI;
        
        int cur=1;
        for(int i=1;i<=llen;i++)
        {
            while(cur<=len && ang[cur]<ang[i]+PI) cur++; //维护单调性
            if(cur-i-1>=2) temp+=C(cur-i-1,2);
        }
        res+=C(n-1,3)-temp;
    }
    
    int main()
    {
        cout.setf(ios::fixed);
        cout.precision(6);
        cin >> n;
        for(int i=1;i<=n;i++) cin >> dat[i].real() >> dat[i].imag();
        
        for(int i=1;i<=n;i++) cal(i);
        
        cout << (res+(C(n,4)-res)*2)/C(n,3)+3.0;
        return 0;
    }

    1、求解凹四边形个数:

    反向求解,利用极角排序对每个点求出不包含其的三角形的个数

    2、对极坐标系的处理

    由于序列是首尾相接的,要将原数组的数+2PI后扩充为原来的两倍,方便处理

    3、对于包含类问题,可以将包含体和被包含点集体考虑

         考虑它们看作一个整体时的性质

  • 相关阅读:
    【字符集及字符编码】UTF-8、UTF-16和UTF-32
    【Android】SQLite基本用法(转)
    【eclipse】导入/导出开发环境(包括编辑器字体颜色大小等)
    一个Android Socket的例子(转)
    Linux中与Windows对应的InterlockedIncrement()函数
    Linux互斥锁pthread_mutex_t
    C++读写文本文件
    C++回调函数调用Java接口抽象函数
    Overlapped I/O模型--事件通知【摘录自《Windows网络编程》】
    Linux C++中需要的头文件
  • 原文地址:https://www.cnblogs.com/newera/p/9062526.html
Copyright © 2020-2023  润新知