• codeforces 600D Area of Two Circles' Intersection


    分相离,内含,想交三种情况讨论一下。

    主要是精度和数据范围的问题,首先数据用long double,能用整型判断就不要用浮点型。

    题目中所给的坐标,半径是整型的,出现卡浮点判断的情况还是比较少的。

    最后算三角型面积的时候不要用海伦公式,有四个连乘很容易爆数据范围损失精度,即使拆开两两乘也要考虑符号

    (取对数也是比较好的办法)。(不知道sqrt和cos,sin的精度如何比较

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long double ld;
    typedef long long ll;
    
    ld x[2],y[2],r[2];
    
    inline ld sqr(ld x){ return x*x; }
    inline ll sqrl(ll x) { return x*x; }
    inline ld fcos(ld a, ld b, ld c)
    {
        return acosl((a*a+b*b-c*c)/(2*a*b));
    }
    
    inline ld cut(ld ang, ld r)
    {
        ld s1 = ang*r*r;
        ld s2 = sinl(ang)*cosl(ang)*r*r;
        return s1 - s2;
    }
    
    const ld pi = acosl(-1);
    
    double solve()
    {
        if(r[0] > r[1]){
            swap(r[0],r[1]);
            swap(x[0],x[1]);
            swap(y[0],y[1]);
        }
        ll dx = x[0]-x[1], dy = y[0]-y[1];
        ll ds = sqrl(dx)+sqrl(dy);
        if(ds >= sqrl(r[0]+r[1])) return 0;
        ld d = sqrtl(ds);
        if(d+r[0] <= r[1]) return sqr(r[0])*pi;
    
        ld ang[2];
        ang[0] = fcos(d,r[0],r[1]);
        ang[1] = fcos(d,r[1],r[0]);
        /*
        WA 28
        ld area = ang[1]*sqr(r[1]) + ang[0]*sqr(r[0]);
        ld s = (d+r[0]+r[1])/2;
        area -= sqrtl(s*(s-d)*(s-r[0])*(s-r[1]))*2; // O(n^4) 拆分会有符号问题 对数也许可行
        return area;
        */
        return cut(ang[0],r[0]) + cut(ang[1],r[1]);
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        cin>>x[0]>>y[0]>>r[0]>>x[1]>>y[1]>>r[1];
        printf("%.10f
    ", solve());
        return 0;
    }
  • 相关阅读:
    Eclipse:构造函数不提示才发现
    Java:终于找到了在alloy中的JFileChooser中的弹出式菜单不显示文字的解决办法
    java:给图片上加水印
    Asp:函数是用传值还是传址
    数据库移植注意事项
    51nod 1009 数字1的数量
    51nod1003 阶乘后面0的数量
    51nod 1002 数塔取数问题
    2017 Multi-University Training Contest
    HDU 3251 Being a Hero 最小割
  • 原文地址:https://www.cnblogs.com/jerryRey/p/5003681.html
Copyright © 2020-2023  润新知