P1378 油滴扩展
题目:https://www.luogu.org/problemnew/show/P1378
难点:计算当前圆是否跟之前的圆产生碰撞 可以计算两点距离然后去掉另一个圆的半径则得到当前圆到另一个圆心得距离 (注意判断两圆相交则扩散半径为0 不能为负数)
#include <iostream>
#include <math.h>
#define pi 3.1415926
using namespace std;
int n,X1,X2,Y1,Y2,x[10],y[10],vis[10];
double r[10],res;
double calc(int i){
double s1=min(abs(x[i]-X1),abs(x[i]-X2));
double s2=min(abs(y[i]-Y1),abs(y[i]-Y2));
//距离哪个点最近
double ans = min(s1,s2);//最近扩散的距离
for(int j = 1; j<=n; j++){
if(i != j && vis[j]){
double d = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));//两点距离公式
ans = min(ans, max(d-r[j], 0.0));//距离-去另一个圆的半径得到当前圆心到另一个圆的边上的距离 取两个的最小值
}
}
return ans;
}
void dfs(int now, double sum){
if(now > n){
res = max(res, sum);
return;
}
for(int i = 1; i<=n; i++){
if(!vis[i]){
r[i] = calc(i);//得出半径
vis[i] = 1;
dfs(now+1, sum + r[i] * r[i] * pi);
vis[i] = 0;
}
}
}
int main(int argc, char** argv) {
cin >> n;
cin >> X1 >> Y1 >> X2 >> Y2;
double s;
s = abs(X1-X2) * abs(Y1-Y2);//长方形面积
for(int i = 1; i<=n; i++){
cin >> x[i] >> y[i];
}
dfs(1,0);
cout << int(s-res+0.5);
return 0;
}