【搜索】油滴扩展

来源:互联网 发布:日程管理app 知乎 编辑:程序博客网 时间:2024/04/28 16:14


From space7油滴扩展       描述 Description    在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pi*r*r,其中r为圆的半径。
       输入格式 Input Format  第1行一个整数N。
第2行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。
接下去N行,每行两个整数xi,yi,表示盒子的N个点的坐标。
以上所有的数据都在[-1000,1000]内。       输出格式 Output Format  一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)

 

生成一个全排列,最后检测,不用剪枝也能过。

一个油滴扩展时,半径是和其他圆相切,和四边相切时求出的半径中最小的一个。

 

一开始错了,因为没有单独讨论油滴在另一个油滴扩展的圆内的情况,这种情况就不能扩展,不单独讨论会变成负面积。。。

 

#include <cstdio>#include <cmath>#include <string>long x[100000];long y[100000];long que[100000];double r[100000];bool used[100000];long top = 0;long X1,X2,Y1,Y2;long n;const double pi = 3.1415926535897932384626433832795;const double eps = 1e-8;double ans = 0;using namespace std; inline double MIN(double a,double b){ return a<b?a:b;}inline double MAX(double a,double b){ return a>b?a:b;}double DIST(long a,long b){ return sqrt(double((x[b]-x[a])*(x[b]-x[a])+(y[b]-y[a])*(y[b]-y[a])));}long getint(){ long rs=0;char tmp;bool sgn=1; do tmp = getchar(); while (!isdigit(tmp)&&tmp-'-'); if (tmp=='-'){sgn=0;tmp=getchar();} do rs=(rs<<3)+(rs<<1)+tmp-'0'; while (isdigit(tmp=getchar())); return sgn?rs:-rs;}void dfs(long l,double sum){ if (l == n+1) {  ans = MAX(sum,ans);  return; } for (long i=1;i<n+1;i++) {  if (!used[i])  {   used[i] = true;   double min = 1e19;   for (long j=1;j<top+1;j++)   {    double dd = DIST(que[j],i);    if (dd > r[j]+eps)     min = MIN(DIST(que[j],i)-r[j],min);    else     min = 0;   }   min = MIN(abs(x[i]-X1),min);   min = MIN(abs(X2-x[i]),min);      min = MIN(abs(y[i]-Y1),min);   min = MIN(abs(Y2-y[i]),min);      que[++top] = i;   r[top] = min;   dfs(l+1,sum + pi*min*min);   used[i] = false;   top--;  } }}int main(){ freopen("oil.in","r",stdin); freopen("oil.out","w",stdout); n = getint(); X1 = getint(); Y1 = getint(); X2 = getint(); Y2 = getint(); for (long i=1;i<n+1;i++) {  x[i] = getint();  y[i] = getint(); } dfs(1,0); printf("%.0lf",abs(X2-X1)*abs(Y2-Y1)-ans); return 0;}

 

原创粉丝点击