P1378 油滴扩展
题目描述
在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pi*r*r,其中r为圆的半径。
输入输出格式
输入格式:
第1行一个整数N。
第2行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。
接下去N行,每行两个整数xi,yi,表示盒子的N个点的坐标。
以上所有的数据都在[-1000,1000]内。
输出格式:
一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)
思路:
用枚举全排列来遍历所有滴入油滴的先后顺序
并判断总空间最大的情况
四舍五入后输出答案
代码解释:
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 double x[10],y[10],xa,xb,ya,yb,ans,r[11]; 5 int n; 6 bool v[10]; 7 double getr(int i)//第i个油滴完全扩散的半径 8 { 9 double s1=min(abs(x[i]-xa),abs(x[i]-xb)); 10 double s2=min(abs(y[i]-ya),abs(y[i]-yb)); 11 double o=min(s1,s2); 12 //为什么是最小的? 13 //因为油滴只要碰到任何一条边都会全部停止扩散 14 for(int l=1;l<=n;l++) 15 { 16 if(v[l]&&l!=i) 17 { 18 double ddd=sqrt((y[l]-y[i])*(y[l]-y[i])+(x[l]-x[i])*(x[l]-x[i])); 19 o=min(o,max(0.0,ddd-r[l])); 20 } 21 }//油滴碰到其他油滴的情况 22 return o; 23 } 24 void dfs(int t,double sum)//t代表该放第t个油滴,sum代表现在的覆盖面积 25 { 26 if(t>n) 27 { 28 ans=max(sum,ans); 29 return ; 30 } 31 else 32 { 33 for(int i=1;i<=n;i++) 34 if(v[i]==0) 35 { 36 v[i]=1; 37 r[i]=getr(i); 38 dfs(t+1,sum+3.1415926*r[i]*r[i]); 39 v[i]=0;//回溯 40 } 41 } 42 } 43 int main() 44 { 45 cin>>n; 46 cin>>xa>>ya>>xb>>yb; 47 for(int i=1;i<=n;i++) 48 cin>>x[i]>>y[i]; 49 double s=abs(xa-xb)*abs(ya-yb);//长方形的面积 50 dfs(1,0); 51 cout<<(int)(s-ans+0.5);//手动四舍五入,那个(int)代表输出向下取整的整型变量(嗷嗷嗷,第一次说的这么专业) 52 return 0; 53 }