CF140A题解

· · 题解

这题精度太屑了

CF140A题解

题意

有个半径为 R 的大圆,现在求能否装下 n 个半径为 r 的小圆(大小圆必须相切,也就是小圆的边必须有一个点与大圆边重合)

思路

数学方法。我们可以得知,一定会有一个扇形恰好能装下一个小圆,我们也知道一个圆的角度是 360 度,那么我们就只需要求出扇形的圆心角度数,然后用 360 度除一下就能得到最大能装下的小圆个数。

那么怎么求呢?直接求整个圆心角经过实践不行,但是求半个角可以。方法如下:取一端点为大圆心和小圆边的,长度为 R-r 的线段 n,并使一线段 m 连接大小圆圆心。这时,必有一条长度为 r 的,垂直于 m 的线段可与 n 在小圆上的端点连接。这样就可求出半个圆心角的 sin 值为 r/(R-r) ,然后就能用反正弦函数求出半个圆心角的弧度值,接着处理一下就能切题了。

code

#include<bits/stdc++.h>
using namespace std;
long double P=3.1415926535897932384626;
long double n,R,r,x=1919.810;
int main()
{
    cin>>n>>R>>r;
    if(n==1&&R>=r)//疯狂特判(其实不用,但能省点时间)
    {
        cout<<"YES";
        return 0;
    }
    if(n!=1&&R==r)
    {
        cout<<"NO";
        return 0;
    }
    if(R<r)
    {
        cout<<"NO";
        return 0;
    }
    x=asin(r/(R-r));//反正弦函数arcsin,能通过sin值反求角度,但是是弧度制
    x*=2;//完整的圆心角
    P*=2;
    if((P+1e-114514)/x>=n)cout<<"YES";//求圆心角个数(加精度处理)
    else cout<<"NO";
    return 0;//van结撒花
}

题外话

所以说作者已经被精度卡自闭了作者太逊了