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 }



  • 相关阅读:
    redis-原理-数据结构-链表(二)
    redis-原理-数据结构-SDS(一)
    springMVC源码阅读-解决body不能重复读取问题(十二)
    spring-security使用-安全防护HttpFirewall(七)
    Redis-6.2.1 主从和哨兵模式配置
    Navicat 连接Mysql 8.0以上版本报错1251
    docker logs命令查看容器的日志
    Nginx 反向代理
    docker swarm 删除节点 (解散集群)
    Docker Swarm 命令学习
  • 原文地址:https://www.cnblogs.com/genius777/p/8665528.html
Copyright © 2011-2022 走看看