codeforces 600D Area of Two Circles' Intersection

本文探讨了两个圆之间的分相离、内含及相交三种情况,并详细介绍了使用longdouble类型来避免精度问题的方法。文章提供了完整的C++代码实现,包括如何计算圆的交叠部分面积等细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

主要是精度和数据范围的问题,首先数据用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\n", solve());
    return 0;
}

 

转载于:https://www.cnblogs.com/jerryRey/p/5003681.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值