题意:源点处有个圆,然后给你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; }