zoukankan      html  css  js  c++  java
  • 题解报告——油滴扩展

    题目描述

    在一个长方形框子里,最多有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

    【思路分析】
    首先很显然,这是一道搜索题,我们所要做得只是枚举每个油滴出现的顺序,然后使这个当前油滴扩展到能扩展到的最大值。
    对于每个油滴的最大半径,就是当前油滴的圆心与其余圆的直线距离的最小值,最后再判一下是不是超过了当前的矩形,最后取每种方案的最大值就好。
    由于n<=6,所以枚举每种滴油滴顺序可以轻松过,这其实就是一道很基础的搜索题(只是有个傻缺不知道思路,让我当回好人
    【代
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int INF=99999999;
     4 const double PI=3.14159265358979323846;
     5 struct sd{
     6     int x,y;
     7 }node[7];
     8 bool vis[7];
     9 int n,lx1,ly1,lx2,ly2;
    10 double min_ans=INF,size;
    11 double r[7];
    12 double dis(sd a,sd b)
    13 {
    14     return sqrt((a.y-b.y)*(a.y-b.y)*1.0+(a.x-b.x)*(a.x-b.x)*1.0);
    15 }
    16 double ask_size(int v)
    17 {
    18     return r[v]*r[v]*PI*1.0;
    19 }
    20 void go_res()
    21 {
    22     double ans=0;
    23     for(int i=1;i<=n;i++)
    24     ans+=ask_size(i);
    25     ans=size-ans;
    26     if(ans<min_ans) min_ans=ans;
    27 }
    28 void deal(int v,int tt)
    29 {
    30     double minn=INF;
    31     int k=0;
    32     for(int i=1;i<=n;i++)
    33     {
    34         if(vis[i]==true&&i!=v)
    35         {
    36             double dd=dis(node[v],node[i]);
    37             if(dd-r[i]<minn)
    38             minn=dd-r[i];
    39         }
    40     }
    41     int l1=node[v].x-lx1;
    42     int l2=node[v].y-ly1;
    43     int l3=lx2-node[v].x;
    44     int l4=ly2-node[v].y;
    45     if(minn>l1) minn=l1*1.0;
    46     if(minn>l2) minn=l2*1.0;
    47     if(minn>l3) minn=l3*1.0;
    48     if(minn>l4) minn=l4*1.0;
    49     r[v]=minn;
    50     if(minn<0) r[v]=0.0;
    51     if(tt==n) go_res();
    52 }
    53 void dfs(int v,int tt)
    54 {
    55     deal(v,tt);
    56     if(tt==n) return;
    57     for(int i=1;i<=n;i++)
    58     {
    59         if(vis[i]==false)
    60         {
    61             vis[i]=true;
    62             dfs(i,tt+1);
    63             vis[i]=false;
    64         }
    65     }
    66 }
    67 int main()
    68 {
    69     memset(vis,false,sizeof(vis));
    70     scanf("%d%d%d%d%d",&n,&lx1,&ly1,&lx2,&ly2);
    71     if(lx1>lx2) {int gg1=lx1;lx1=lx2;lx2=gg1;}
    72     if(ly1>ly2) {int gg2=ly1;ly1=ly2;ly2=gg2;}
    73     size=(lx2-lx1)*(ly2-ly1)*1.0;
    74     for(int i=1;i<=n;i++)
    75         scanf("%d%d",&node[i].x,&node[i].y);
    81     for(int i=1;i<=n;i++)
    82     {
    83         vis[i]=true;
    84         dfs(i,1);
    85         vis[i]=false;
    86     }
    87     double gg=min_ans;
    88     int res=gg;
    89     gg=gg-res;
    90     if(gg>=0.5) res++;
    91     printf("%d",res);
    92     return 0;
    93 }



  • 相关阅读:
    TCP源码—连接建立
    TCP系列02—连接管理—1、三次握手与四次挥手
    TCP系列01—概述及协议头格式
    ubuntu软件管理apt与dpkg
    318. Maximum Product of Word Lengths
    317. Shortest Distance from All Buildings
    316. Remove Duplicate Letters
    315. Count of Smaller Numbers After Self
    314. Binary Tree Vertical Order Traversal
    313. Super Ugly Number
  • 原文地址:https://www.cnblogs.com/genius777/p/8665528.html
Copyright © 2011-2022 走看看