题目描述
在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pi*r*r,其中r为圆的半径。
输入输出格式
输入格式:
第1行一个整数N。
第2行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。
接下去N行,每行两个整数xi,yi,表示盒子的N个点的坐标。
以上所有的数据都在[-1000,1000]内。
输出格式:
一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)
输入输出样例
输入样例#1:
2
20 0 10 10
13 3
17 7
输出样例#1:
50
枚举全排列,暴搜。
注意精度。
算一个油滴和已有油滴距离时,可能算到负值,那么这时应选择r=0(不滴)
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const double pi=3.141592653; 9 const int mxn=12; 10 struct point{ 11 double x,y; 12 double r; 13 }p[mxn]; 14 double ans; 15 int n; 16 bool vis[mxn]; 17 double ex1,ex2,ey1,ey2; 18 double dist(int a,int b){ 19 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)); 20 } 21 double CLS(double r){ 22 return r*r*pi; 23 } 24 void DFS(double smm,int cnt){ 25 if(cnt>n){ 26 ans=max(ans,smm); 27 return; 28 } 29 int i,j; 30 for(i=1;i<=n;i++){ 31 if(vis[i])continue; 32 double tmp=1e9+7; 33 tmp=min(tmp,abs(p[i].x-ex1)); 34 tmp=min(tmp,abs(p[i].y-ey1)); 35 tmp=min(tmp,abs(ex2-p[i].x)); 36 tmp=min(tmp,abs(ey2-p[i].y)); 37 for(j=1;j<=n;j++){ 38 if(j!=i && p[j].r) tmp=min(tmp,dist(i,j)-p[j].r); 39 } 40 if(tmp<0)tmp=0; 41 p[i].r=tmp; 42 vis[i]=1; 43 // res+=CLS(tmp); 44 DFS(smm+CLS(tmp),cnt+1); 45 vis[i]=0; 46 p[i].r=0; 47 } 48 return; 49 } 50 int main(){ 51 scanf("%d",&n); 52 int i,j; 53 scanf("%lf%lf%lf%lf",&ex1,&ey1,&ex2,&ey2); 54 if(ex1>ex2)swap(ex1,ex2); 55 if(ey1>ey2)swap(ey1,ey2); 56 for(i=1;i<=n;i++){ 57 scanf("%lf%lf",&p[i].x,&p[i].y); 58 } 59 DFS(0,1); 60 double S=abs(ex1-ex2)*abs(ey1-ey2); 61 // printf("%.5f ",S); 62 printf("%.0f",(S-ans)); 63 return 0; 64 }