HDU 6354 Everything Has Changed(余弦定理)多校题解

题意:源点处有个圆,然后给你m个圆(保证互不相交、内含),如果源点圆和这些原相交了,就剪掉相交的部分,问你最后周长(最外面那部分的长度)。

思路:分类讨论,只有内切和相交会变化周长,然后乱搞就行了。题目好像不用讨论给的圆包含源点圆的情况(0?),那么只剩内含(不变)、相切(增加小圆周长)、相离(不变)、相交(余弦定理求一下)。余弦定理都快忘了,本来打算构建rt三角形233。学到一招pi = acos(-1.0)。

代码:

#include<cstdio>
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 100+10;
const int INF = 0x3f3f3f3f;
double dis(double x1,double y1){
    return sqrt(x1 * x1 + y1 * y1);
}
int main(){
    int T;
    double pi = acos(-1.0);
    char n[12];
    scanf("%d",&T);
    while(T--){
       double ans;
       double R;
       int m;
       scanf("%d%lf",&m,&R);
       ans = 2 * R * pi;
       while(m--){
           double x,y,r;
           scanf("%lf%lf%lf",&x,&y,&r);
           double dist = dis(x,y);
           if(dist + r == R){
                ans += 2 * r * pi;
           }
           else if(dist >= r + R || dist + r < R){
                continue;
           }
           else{
                double del = acos((R * R + dist * dist - r * r) / (2 * dist * R));
                double si = acos((r * r + dist * dist - R * R) / (2 * dist * r));
                ans = ans - del * R * 2 + si * r * 2;
            }
       }
       printf("%lf\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/KirinSB/p/9489321.html