P1378

油滴扩展

题目描述

在一个长方形框子里,最多有 \(N\) 个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这 \(N\) 个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)

注:圆的面积公式 \(V = \pi r^2\),其中 \(r\) 为圆的半径。

输入格式

第一行,一个整数 \(N\)

第二行,四个整数 \(x, y, x', y'\),表示长方形边框一个顶点及其对角顶点的坐标。

接下来 \(N\) 行,第 \(i\) 行两个整数 \(x_i, y_i\),表示盒子内第 \(i\) 个点的坐标。

输出格式

一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)。

样例 #1

样例输入 #1

2
20 0 10 10
13 3
17 7

样例输出 #1

50

提示

对于 \(100\%\) 的数据,\(1 \le N \le 6\),坐标范围在 \([-1000, 1000]\) 内。

dfs

一遍过还是不错

#include<bits/stdc++.h>
using namespace std;
int n,sx,sy,tx,ty;
const double pi=acos(-1);
struct did {
	int x,y;
} a[15];
int vis[15];
double r[15];
double maxx=0.0;
double dis(double x,double y,double xx,double yy) {
	return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
void dfs(int num,double ans) {
	if(num==n+1) {
		if(ans>maxx+1e-6)maxx=ans;
		return ;
	}
	for(int i=1; i<=n; i++) {
		if(vis[i])continue;
		double R;
		int x=a[i].x,y=a[i].y;
		R=min(min(abs(x-sx),abs(x-tx)),min(abs(y-sy),abs(y-ty)));
		for(int j=1; j<=n; j++) {
			if(j==i)continue;
			if(r[j]<0)continue;
			R=min(R,dis(x,y,a[j].x,a[j].y)-r[j]);
		}
		vis[i]=1;
		if(R<0.0)R=0.0;
		r[i]=R;
		dfs(num+1,ans+pi*R*R);
		vis[i]=0;
		r[i]=-1;
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1; i<=n; i++)r[i]=-1;
	cin>>sx>>sy>>tx>>ty;
	double S=(double)(abs(sx-tx))*(double)(abs(sy-ty));
	for(int i=1; i<=n; i++)cin>>a[i].x>>a[i].y;
	dfs(1,0.0);
	printf("%.0lf\n",S-maxx);
	return 0;
}
posted @ 2023-05-25 20:30  N0zoM1z0  阅读(17)  评论(0编辑  收藏  举报