美文网首页
2018年Java方向C组第十题

2018年Java方向C组第十题

作者: D丝学编程 | 来源:发表于2021-04-01 14:58 被阅读0次

如果已知了测试塔的高度,并且采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

输入数据,一个整数n(3<n<10000),表示测试塔的高度。
输出一个整数,表示最多测试多少次。

例如:
输入:
3

程序应该输出:
2

解释:
手机a从2楼扔下去,坏了,就把b手机从1楼扔;否则a手机继续3层扔下

再例如:
输入:
7

程序应该输出:
3

解释:
a手机从4层扔,坏了,则下面有3层,b,c 两部手机2次足可以测出指数;
若是没坏,手机充足,上面5,6,7 三层2次也容易测出。

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。


笨笨有话说:
我觉得3个手机太难了,要是2个手机还可以考虑一下。

歪歪有话说:
想什么呢,你!要是1部手机还用你编程啊?那样的话只好从下往上一层一层测。

解析:

Scanner input = new Scanner(System.in);
int fNum = input.nextInt();   //输入楼层高度
int pNum = 3;   //手机数量为3
//定义二维数组,pNum+1行,fNum+1列,+1因为我们从下标1开始使用数组,使用更加方便
//行和列交叉的值保存最终测试次数,例如arr[2][4]里面存储2部手机4层楼需要测试几次。
//题目实际上是要得到数组最后一个元素值,但是我们必须存储所有元素值,因为数组后面的值需要根据前面的值计算出来
int[][] arr = new int[pNum+1][fNum+1];  
for (int i = 1; i < arr.length; i++) {
    for (int j = 1; j < arr[i].length; j++) {
        //如果是只有1楼,那么测试数量就是1
        //如果只有一部手机,楼层数量就是测试数量,
        //并且手机数量越多,测试数量肯定越少,
        //如此赋值后,第一行和第一列是正确的值,其它数组元素值是所有方案中的最大值。
        arr[i][j] = j;
    }
}
//需要理解的部分:
//假设pNum个手机,fNum层楼,开始从任意一层X层丢手机,测试次数如下,两种情况
//手机摔坏:测试次数arr[pNum][fNum] = arr[pNum-1][X-1]
//手机完好:测试次数arr[pNum][fNum] = arr[pNum][fNum-X]
//从X层丢手机只是一种方案,题目意思是要求最优方法的最大值,所以在此单独方案下,求测试次数
//实际上是求该方案下的最大值,即:
//Math.max(arr[pNum-1][X-1],arr[pNum][fNum-X])

//从第二个手机开始循环,因为一个手机的时候arr数组里面已经是正确值了
for (int p = 2; p <= pNum; p++)  
{
    //从第二层楼开始循环,因为第一层楼的时候arr数组里面已经是正确值了
    for (int f = 2; f <= fNum; f++) 
    {
        //此循环求一共p个手机,f层楼的测试次数
        //遍历所有方案,即从第1,第2,。。。直到第f层楼开始先扔手机
        for (int i = 1; i <= f; i++) 
        {
            //Java中int类型数组元素默认值为0,所以当i-1或f-i等于0的时候实际上向上和向下是没有次数的,
            //正好和0的值匹配,不影响程序
            int wrong = arr[p-1][i-1] + 1;  //手机摔坏的情况
            int good = arr[p][f-i] + 1;       //手机完好的情况
            //求最优方案的最大测试次数,所以本次方案次数为
            int count = Math.max(wrong, good);
            //由于arr存储的是最优方案,所以把本次方案需要和以前方案比较得到最小值
            arr[p][f] = Math.min(arr[p][f], count);
            //举例循环第一次p=2,f=2,i=1,即求2部手机,2层楼的次数
            //wrong = arr[p-1][i-1] + 1 = arr[1][0] + 1 =0 + 1 = 1
            //good = arr[p][f-i]+1 = arr[2][1] + 1 = 1+1=2
            //count = Math.max(wrong, good) = 2
            //arr[2][2] = Math.min(arr[p][f], count) = Math.min(2, 2) = 2
            //就这样依次循环下去可以将arr数组所有元素全部填满,最后一行,最后一列就是题目要的答案
        }
    }
}
System.out.println(arr[pNum][fNum]);

备注:具体图解如下:
(1)数组定义:


捕获.PNG

(2)过程推理


捕获.PNG

相关文章

  • 2014年Java方向C组第十题

    标题:矩阵翻硬币 小明先把硬币摆成了一个 n 行 m 列的矩阵。 随后,小明对每一个硬币分别进行一次 Q 操作。 ...

  • 2015年Java方向C组第十题

    标题:垒骰子 赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。经过长期观察...

  • 2018年Java方向C组第十题

    如果已知了测试塔的高度,并且采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢? 输入数据,一...

  • 2016年Java方向C组第十题

    密码脱落 X星球的考古学家发现了一批古代留下来的密码。这些密码是由A、B、C、D 四种植物的种子串成的序列。仔细分...

  • 2017年Java方向C组第十题

    标题:图形排版 小明需要在一篇文档中加入 N 张图片,其中第 i 张图片的宽度是 Wi,高度是 Hi。 假设纸张的...

  • 9、正则表达式

    注:第0组(d(a(b))(c))第1组 d(a(b))(c)第2组 a(b)第3组 b 一、正则表达式的概述和简...

  • 浅谈学好java需要熟练掌握的知识

    个人是从C++方向转到JAVA方向的新手,个人认为学号JAVA需要从以下方面入手,学好下面那些知识,JAVA基本可...

  • 2014年Java方向C组第八题

    标题:兰顿蚂蚁 兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。 平面上的正方形格子被填上...

  • 2014年Java方向C组第九题

    标题:地宫取宝 X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。 ...

  • 2015年Java方向C组第二题

    第二题 标题:立方尾不变 有些数字的立方的末尾正好是该数字本身。比如:1,4,5,6,9,24,25,.... 请...

网友评论

      本文标题:2018年Java方向C组第十题

      本文链接:https://www.haomeiwen.com/subject/cetrxltx.html