zoukankan      html  css  js  c++  java
  • LG1378

    题目描述

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




    我的大思想肯定是暴力先枚举(肯定有其他更快的方法,但我先只想把样例起码给过了把)
    我觉得对于给定的点,肯定要算五个参数,首先4个分别是距离四条边的距离,至于另一个距离则是该油滴距离另一个油滴的距离。(在样例仅有2个油滴的情况
    下)
    然后样例应该挺好过的,
    怎么都没了?
    因为要滴六个东西,所以6!=720种顺序倒是确实。
    用dfs枚举排列。
    确定搜索目标和搜索顺序。
    1,搜索目标:选出滴油的顺序。
    2,搜索状态:x,为选到第几个油滴
    例题嘛,跟着人家吃透就好。
    我觉得这个题有点玄幻。。
    tm的难死了。。。
    先用一个人的题解弄懂些,然后再看有没有和网课上讲的类似的。
    对待别人的代码,最好还是懂了别人的思路,然后根据自己对于题意得理解
    往下写,不管怎么样还是要自己多思考


    对待这个题终于强了一点,一个是看懂回溯,一个是看懂被覆盖的情况。

    为什么选数不需要回溯?》
    碰到的问题还挺多的
    首先在还没有过样例的时候,
    1,如果出现了编译的时候,跳出了一个
    stl_algobase
    的东西,可能你是比较函数min或者max用错了,一般的错误是里面比较了两个以上的东西。
    2,

    invalid types 'int[int]' for array subscript

    可能和你变量名,特别是和数组的变量名给重复了。

    3,对了还有个

    xpected primary-expression before '.' token

    跟你的定义函数的时候也定义参数了,你咋输出人家的参数了。

    我今天,,说实话,这个东西挺多的。

    从大的题意上来说,我们就知道了是枚举然后计算就OK了

    而且一般也不需要剪枝,因为你看数据范围是6,最多有6!=720种情况。

    好了既然大方向有了,那么需要的是三个函数,

    主函数

    枚举函数

    计算函数

    先解决主函数,即输入问题,

    1,你发现输入的数据在[-1000,1000]这个区间上。有负数那么怎么办》

    其实就是一个平移的思想了,输入的东西全给它加上1000;

    2,关于这几个输入数据的存入,我其实也学到不少。

    3,另外还要注意,结果是要四舍五入,也就是有double类型的数据在其中混着,这个确实需要我们着实注意注意。

    自然设涉及到强制转换?---+0.5?哈哈倒是没有什么难度。

    至于枚举函数,

    搜索问题,涉及搜索目标和状态,

    搜索目标,找到拓展面积最大的所滴的顺序。

    搜索状态,令x为当前要滴的是第几滴,s为当前扩展的顺序。

    其实。。。除过搜索,核心的是求那个半径的值。

    那么里面第一步,先边界呗,if(x>n)

    ans=max(ans,s)

    return ;这样

    就是预处理呗。

    第二步,遍历

    for(int i=1;i<=n;i++)

    {

    if(flg[i])

    {int temp=0;

    for(int j=1;j<=n;j++)//是个遍历里面的预处理,判断它是否被覆盖//话说这个最早开始的我就没想过,唉,划水啊,还是要自己思考否则没啥用。。

    {if(flg[i]&&r[i]>=sqrt())

    {

    tt=1;

    flg[i]=1;

    dfs(x+1,0)

    flg[i]=0;

    }

    if(tt=1)

    continue;

    if(

    }

    }

    }

    我在这直接写代码好像不太好

    先写思路把

    void dfs()

    {  if~~~(这个是判断是否枚举超过需要的次数)

    for(in ti)//这个是开始遍历

    {if(flg[i])//这个是枚举前的预处理,看是否已经被扩展过。

    {int tt=0;

    for(int i)//这个 算是这个里面的预处理吧,看是否被覆盖过,覆盖过直接进入下一层递归。

    接下是是确定r[i],和两个顶点的x比较,和两个顶点的y比较。最后在和已经扩展的比较。

    注意这里的比较函数,min,max需要自己写,因为你比较的数会是double类型的,而自带的函数值比较int型的。

    确定好r[i]就开始进入下一层递归。

    }

    }

    }

    好像也没啥的。。

    但是需要定义的东西我得重新想下

    int 油滴数,顶点坐标,区域坐标,bool油滴数,答案,循环数,辅助函数,等

    写吧.

    1,这个定义pi这个东西叫啥来着?

    好像是叫宏定义,而且后面不用加分号;

    第一遍敲完,修修补补完,竟然100ac了???

    真tm爽!!

    先来分析下错误

    1,第一个错误是枚举的时候,我写成了if(flg[i]),,这不显然有问题嘛。。枚举肯定是没扩展过的呗。。

    2,第二个错误是,在特判,是否被覆盖后,没有标记该点。

    3,第三个错误是,double ans,这个答案从一开始就是double类型的。我成int类型的了。

    4,第四个类似于第三个,半径r都忘设了,而且定义类型的时候又错了一遍。

    这个有点不能忍,因为毕竟,求面积,其实就是半径。

    5,第五个没找到。。。

    6,定义辅助函数,min和max的时候,里面的参数类型double是对的。。。但是返回值也要double 啊。。

    7,再就是辅助函数可以加inline ,

    这是一个关键字可一解决关于大量调用某函数而导致消耗栈空间过多的。

    使之成为内联函数。

    8,两种情况你可以用双目运算符的

    9,和其他已经扩展的比较,

    比错了。

    找个时间再敲一遍吧。

    我现在想了一想,关于之前犯的错误,我想的,觉得还是考虑不全面,给的数据确实是整数,

    但是在与四边比较的过程中,(因为整数的原因),肯定也都是整数,

    但是问题就是出在了,在和其他扩展的油滴的比较中,却不一定是,整数

    说是这个比较,实际上是看的是两点间的距离啊。。这个没考虑到,

    所以主要出现了那几个错误。

    而且由于pai的存在,ans也得是double类型的。

    回溯的话,我希望你能够再模拟一下,我觉得我理解的不够。

  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/beiyueya/p/11909711.html
Copyright © 2011-2022 走看看