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 }

 

 

posted @ 2018-07-17 12:16  qkm  阅读(75)  评论(0编辑  收藏  举报