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
啊啊啊啊,太可恶了,又打错了变量
#include<iostream> #include<queue> #include<cstdio> #include<algorithm> #include<math.h> #include<string.h> using namespace std; #define pi 3.141592653 int n; double x11,x22,y11,y22,ans; double d[10][10],x[10],y[10],r[10]; bool vis[10]; double abss(double x) { if(x>0.000) return x; return -x; } double R(int i) { double q=99999.2; double s1=min(abss(x[i]-x11), abss(x[i]-x22)); double s2=min(abss(y[i]-y11), abss(y[i]-y22)); q=min(s1,s2); for(int j=1;j<=n;j++) if(i!=j && vis[j]) q=min(q,d[i][j]-r[j]); if(q<=0.000) q=0.0; return q; } void dfs(int xx,double tot) { if(xx>n) {ans=max(ans,tot);return ;} for(int i=1;i<=n;i++) if(!vis[i]) { r[i]=R(i);vis[i]=1; dfs(xx+1,tot + r[i]*r[i]*pi ); r[i]=0;vis[i]=0; } } int main() { scanf("%d",&n); scanf("%lf%lf%lf%lf",&x11,&y11,&x22,&y22); for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ); double all=(abss( x11-x22 )*abss( y11-y22 )); dfs(1,0); ans=all-ans+0.5; cout<<(int )ans; return 0; }