题目描述 Description
在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pi*r*r,其中r为圆的半径。
注:圆的面积公式V=pi*r*r,其中r为圆的半径。
标签:
2
20 0 10 10
13 3
17 7
50
分析:没什么号分析的……大暴搜啊……dfs出全排列,对每种情况计算。计算最小半径的时候别忘了包含情况,即圆心已被其他圆覆盖。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namespace std; const double pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679; double x[10],y[10],r[10],maxn; int a[10],n,sum; bool v[10]; double cd(int i,int j) { return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); } void calc() { double ans=0,dist; for (int i=1;i<=n;i++) { r[i]=min(x[a[i]]-x[0],x[n+1]-x[a[i]]); r[i]=min(r[i],y[a[i]]-y[0]); r[i]=min(r[i],y[n+1]-y[a[i]]); for (int j=1;j<i;j++) { dist=cd(a[j],a[i]); r[i]=min(r[i],dist-r[j]); } if (r[i]<0) r[i]=0; //关键 ans+=pi*r[i]*r[i]; } maxn=max(maxn,ans); } void dfs(int k) { if (k==n+1) { calc(); return; } for (int i=1;i<=n;i++) if (!v[i]) { a[k]=i; v[i]=1; dfs(k+1); v[i]=0; } } void doit() { double t; if (x[0]<x[n+1]&&y[0]<y[n+1]) return; if (x[0]<x[n+1]&&y[0]>y[n+1]) { t=y[0]; y[0]=y[n+1]; y[n+1]=t; return; } if (x[0]>x[n+1]&&y[0]<y[n+1]) { t=x[0]; x[0]=x[n+1]; x[n+1]=t; return; } if (x[0]>x[n+1]&&y[0]>y[n+1]) { t=x[0]; x[0]=x[n+1]; x[n+1]=t; t=y[0]; y[0]=y[n+1]; y[n+1]=t; return; } } int main() { scanf("%d",&n); scanf("%lf%lf%lf%lf",&x[0],&y[0],&x[n+1],&y[n+1]); doit(); //一开始写的太拙了,不要在意这些细节,根本没用。 for (int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); memset(v,0,sizeof(v)); memset(a,0,sizeof(a)); dfs(1); printf("%.0lf",(x[n+1]-x[0])*(y[n+1]-y[0])-maxn); return 0; }
标签:
原文地址:http://www.cnblogs.com/ws-fqk/p/4470880.html