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;
}
原文地址:https://www.cnblogs.com/CLGYPYJ/p/7304934.html