给n个圆要么包含,要么相分离,没有两个公共点,当成一棵树,把包含的面积大的放在上面
如图最上面的par记为-1,level记为0,当par==-1||level==1时就加否则减,
就是第一,二层先加,第三层减,然后后面的一直交替就行了
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=1000+10,maxn=111117,inf=11111; ll x[N],y[N],r[N]; int par[N]; bool level[N]; vector<int>v[N]; void dfs(int i,bool f) { level[i]=f; for(int j=0;j<v[i].size();j++) dfs(v[i][j],f^1); } int main() { ios::sync_with_stdio(false); cin.tie(0); cout<<setiosflags(ios::fixed)<<setprecision(9); int n; cin>>n; memset(level,0,sizeof level); memset(par,-1,sizeof par); for(int i=0;i<n;i++)cin>>x[i]>>y[i]>>r[i]; for(int i=0;i<n;i++) { par[i]=-1; for(int j=0;j<n;j++) if(r[j]>r[i]&&(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])<=(r[i]-r[j])*(r[i]-r[j])) if(par[i]==-1||r[par[i]]>r[j]) par[i]=j; v[par[i]].push_back(i); } for(int i=0;i<n;i++) if(par[i]==-1) dfs(i,0); double ans=0.00; for(int i=0;i<n;i++) ans+=pi*r[i]*r[i]*(par[i]==-1||(level[i]==1) ? +1:-1); cout<<ans<<endl; return 0; }
时间: 2024-10-11 22:32:58