• 摔杯算法(要求用最少的测试次数找出恰巧会使杯子破碎的楼层。)


    题目: 一种杯子,若在第N层被摔破,则在任何比N高的楼层均会破;若在第M层不破,则在任何比M低的楼层均不会破。给你两个这样的杯子,让你在100层高的楼层中测试,要求用最少的测试次数找出恰巧会使杯子破碎的楼层。

    解题思路:

    1个杯子尝试的次数假设为n, 则可能尝试有1次, 2次, 3次,...,n次, 但,要求最少的测试次数(楼层不可能重复), 所以尝试总数还应该是这次大于等于100, 上次计算得出的尝试总数小于100

    即1+2+3+...+n >= 100

    简化公式: 1/2n(n+1) >= 100

    求得n的最小整数为14

    1. function bei({n}) {
    2. let currentNum = 0
    3. if(n == 1) return {n:1}
    4. if(n > 1 && n <= 100) {
    5. const obj = bei({n: n - 1})
    6. if(typeof obj === 'object') {
    7. const pre = obj.n; // 上次尝试总数
    8. currentNum = n + pre // 此次尝试总数
    9. if(currentNum >= 100 && pre < 100) {
    10. console.log(n, pre, currentNum)// 14 91 105
    11. print(n)
    12. return
    13. }
    14. return {n:currentNum, parts: n}
    15. }
    16. }
    17. }
    18. function print(minNum) {
    19. console.log(minNum) // 14
    20. }
    21. bei({n:100})

    优化: 除了最小值, 其他可能的区间:

    1. var arr = []
    2. function bei2({ n, step }) {
    3. let currentNum = 0
    4. const end = n + step - 1
    5. if (end) {
    6. arr.push([n, end])
    7. if (n >= 100) {
    8. return
    9. }
    10. const start = end
    11. const end2 = start + step - 1
    12. if (start > end2) return
    13. return end + 1 >= 100 ? arr.push([100]) : bei2({ n: end + 1, step: step - 1 })
    14. }
    15. // 计算第一个最小测试区间, 后面的区间数字间隔逐渐变小
    16. while (n >= 1 && n <= 100) {
    17. currentNum += n // 此次尝试总数
    18. if (currentNum >= 100) {
    19. arr.push([1, n])
    20. print(n)
    21. return bei2({ n: n + 1, step: n - 1 })
    22. }
    23. n++
    24. }
    25. }
    26. bei2({ n: 1 })
    27. console.log(arr)
    28. // 一种杯子,若在第N层被摔破,则在任何比N高的楼层均会破,若在第M层不破,则在任何比M低的楼层均会破,给你两个这样的杯子,让你在100层高的楼层中测试,要求用最少的测试次数找出恰巧会使杯子破碎的楼层。
    29. // 第一个杯子可能的投掷楼层分别为:14,27,39,50,60,69,77,84,90,95,99,100
    30. // 14 + 13 => 27
    31. // 27 + 12 = 39
    32. // 39 + 11 => 50
    33. // 50 + 10 => 60
    34. // 60 + 9 => 69
    35. // 69 + 8 => 77
    36. // 77 + 7 => 84
    37. // 84 + 6 => 90
    38. // 90 + 5 => 95
    39. // 95 + 4 => 99
    40. // 最大100

    当我们用14时,我们可以得出范围为1~14,  15~27,  28~39... 96~99, 100

    参考地址: 100层楼两个杯子找杯子碎的临界点-CSDN博客

  • 相关阅读:
    《从零开始的Java世界》01基本程序设计
    认识ICMP协议 —— ping命令的作用过程
    数据可视化时代,为智慧城市建设添彩_光点科技
    用ts类型要描述 1到100范围的数字
    隐语 Meetup 北京站|精彩时刻大盘点!新品发布、行业案例、专家解读......欢迎围观
    Spring事务失效的八种场景
    electron安装失败时配置
    128天创作纪念日
    商城免费搭建之java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c
    leetcode写题笔记 -- 罗马数字转整数
  • 原文地址:https://blog.csdn.net/qq_42750608/article/details/134341208