題解 P1378 【油滴擴展】
阿新 • • 發佈:2018-11-07
dfs efi span void [1] == 一個 lin for
題面
在一個長方形框子裏,最多有N(0≤N≤6)個相異的點,在其中任何一個點上放一個很小的油滴,那麽這個油滴會一直擴展,直到接觸到其他油滴或者框子的邊界。必須等一個油滴擴展完畢才能放置下一個油滴。那麽應該按照怎樣的順序在這N個點上放置油滴,才能使放置完畢後所有油滴占據的總體積最大呢?(不同的油滴不會相互融合)
註:圓的面積公式V=pi*r*r
,其中r為圓的半徑。
題意
再規定的矩形內可以滴幾個油滴,油滴滴的順序不做要求,但是油滴滴的位置有要求。另外油滴滴在矩形內會一直擴展,直至碰著另一個油滴,或者撞到邊界。
求矩形盒子內滴完油滴剩余的最小空間。
題解
我的思路很不好,為防誤導,直接講這題跑到\(0ms\) 大神的思路和代碼。
代碼
#include<stdio.h> #include<math.h> #define PI 3.1415926 int n,vis[7]; double A[7][2],x,y,x2,y2,R[7],max,dis[7][7]; double abss(double a){return a>0.0?a:-a;} void dfs(int step,double s) {//準備放置第step個油滴,放置前面積為s int k,i; double r=0;//準備放置的油滴的擴散半徑 if(step==n+1)//放完 max=s>max?s:max; else for(k=1;k<=n;k++) if(!vis[k]) { //矩形和已放置的油滴約束了r的大小 r=abss(y2-A[k][1]); if(r>abss(x2-A[k][0])) r=abss(x2-A[k][0]); if(r>abss(y-A[k][1])) r=abss(y-A[k][1]); if(r>abss(x-A[k][0])) r=abss(x-A[k][0]); for(i=1;i<=n;i++) if(vis[i]) if(r>dis[k][i]-R[i]) r=dis[k][i]-R[i]; r=r<0?0:r;//註意r不能為負 vis[k]=1;R[k]=r; dfs(step+1,s+PI*r*r); vis[k]=0;R[k]=0.0; } } int main(void) { int i,j; scanf("%d%lf%lf%lf%lf",&n,&x,&y,&x2,&y2); for(i=1;i<=n;i++) scanf("%lf%lf",&A[i][0],&A[i][1]); //預處理出油滴間距dis for(i=1;i<=n;i++) for(j=1;j<i;j++) if(i!=j) dis[i][j]=dis[j][i]=sqrt((A[i][0]-A[j][0])*(A[i][0]-A[j][0])+ (A[i][1]-A[j][1])*(A[i][1]-A[j][1])); dfs(1,0.0); double S=abss(x-x2)*abss(y-y2);//矩形面積 printf("%.0lf",S-max); return 0; }
題解 P1378 【油滴擴展】