码迷,mamicode.com
首页 > 其他好文 > 详细

[洛谷P1378] 油滴扩展

时间:2015-05-01 17:17:18      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

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

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;
}

 

[洛谷P1378] 油滴扩展

标签:

原文地址:http://www.cnblogs.com/ws-fqk/p/4470880.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!