luogu 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:
2 20 0 10 10 13 3 17 7
输出样例#1:
50
因为N很小所以爆搜就可以,
注意函数的返回值也是double
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 8 const double pi=acos(-1);//3.1415926; 9 10 int n,a,b,c,d; 11 12 struct Node{ 13 int x,y; 14 }node[10]; 15 int edge[10]; 16 double ans=-1; 17 double calc(int x1,int y1,int x2,int y2) 18 { 19 return sqrt((double)(x1-x2)*(double)(x1-x2)+(double)(y1-y2)*(double)(y1-y2)); 20 } 21 22 bool vis[7]; 23 double r[7];int mx[7]; 24 25 void rember() 26 { 27 double sum=0; 28 for(int i=1;i<=n;i++) 29 { 30 sum+=pi*r[i]*r[i]; 31 } 32 ans=max(ans,sum); 33 34 } 35 36 void dfs(int step) 37 { 38 if(step>n) rember(); 39 for(int i=1;i<=n;i++) 40 { 41 if(!vis[i]) 42 { 43 r[i]=mx[i]; 44 vis[i]=1; 45 for(int j=1;j<=n;j++) 46 { 47 if(vis[j]&&i!=j) 48 { 49 double dis=calc(node[j].x,node[j].y,node[i].x,node[i].y); 50 dis-=r[j]; 51 r[i]=min(r[i],dis); 52 if(r[i]<0)r[i]=0; 53 } 54 } 55 dfs(step+1); 56 vis[i]=0; 57 } 58 } 59 } 60 61 int main() 62 63 { 64 scanf("%d%d%d%d%d",&n,&a,&b,&c,&d); 65 double s=(double)(a-c)*(double)(b-d); 66 if(s<0) s=-s; 67 memset(mx,0x7fffff,sizeof(mx)); 68 for(int i=1;i<=n;i++) 69 { 70 scanf("%d%d",&node[i].x,&node[i].y); 71 mx[i]=min(min(abs(a-node[i].x),abs(c-node[i].x)),min(abs(b-node[i].y),abs(d-node[i].y))); 72 } 73 dfs(1); 74 ans=s-ans; 75 int anss=floor(ans); 76 if((double)ans-anss>=0.5) 77 anss++; 78 printf("%d",anss); 79 return 0; 80 }