zoukankan      html  css  js  c++  java
  • [洛谷P1378] 油滴扩展|搜索

     题目描述 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;
    }
  • 相关阅读:
    从零开始学习Sencha Touch MVC应用之二
    PHPMailer IIS下的PHP脚本使用GMAIL发送邮件PHP
    php群发邮件
    PHP编辑器
    PHP使用GET传输汉字的编码转换
    转一个手机开发的帖子(来自开发者俱乐部)
    Zend_Mail收发smtp(gmail,163)邮件Zend Framework
    just a simple for a mail() amd get array()
    ecshop二次开发 结构分析和代码研究 呵呵
    如何重置Drupal 7的用户密码
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4470880.html
Copyright © 2011-2022 走看看