题意:给你一个坐标轴,里面有一些圆,在这个圆的覆盖区域中如果有奇数个圆覆盖就加上这块覆盖区域,如果有偶数个圆覆盖就减去这块区域,现在可以将
这个平面一分为2,求最大的区域和;
题解:这道题表面上是求最优解问题,实际上是答案是个定值,仔细想一想,首先从最简单的情况分解问题
如果是这个圆的话没有被别的圆覆盖的话就加上,如果这个圆被一个圆覆盖的话也加上,相当于把他放到第二个平面中,如果放到第一个平面中就是减去,但是被他覆盖的
所有圆的面积加起来都比他小(只考虑比当前层数小的一层,嵌套覆盖的情况按照这个思路考虑),相当于每次都把面积大的那个保留了下来
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
typedef long long LL;
struct node
{
double x, y, r;
}p[N];
double dist(int a,int b)
{
return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
const double pi=acos(-1.0);
int main()
{
int n;
scanf("%d", &n);
for(int i=1;i<=n;i++) scanf("%lf %lf %lf",&p[i].x,&p[i].y,&p[i].r);
double ans=0;
for(int i=1;i<=n;i++)
{
int cnt=0;
for(int j=1;j<=n;j++)
{
if(i==j) continue;
double d=dist(i,j);
if(d<p[j].r&&p[j].r>p[i].r) cnt++;
}
if(cnt%2==0&&cnt!=0) ans-=p[i].r*p[i].r;
else ans+=p[i].r*p[i].r;
}
printf("%.10f\n",ans*pi);
return 0;
}