最小周长巧克力板组合 | 豆包MarsCode AI刷题

80 阅读3分钟

题目链接
最小周长巧克力板组合 - MarsCode

问题描述
小U准备了一些边长为整数的正方形巧克力板,希望选出若干块巧克力板,使它们的总面积恰好等于给定的整数n。巧克力板的周长应尽可能小。巧克力板的总面积恰好为n,而总周长为这些正方形边长的四倍和。请你帮助小U找到一个最优方案,输出最短的周长总和。

测试样例
样例1:

输入:n = 11
输出:20

样例2:

输入:n = 13
输出:20

样例3:

输入:n = 25
输出:20

问题分析
这是一道贪心问题,贪心就是每一次选择局部最优,从而达到全局最优。解决贪心问题的关键在于怎么从局部最优推出全局最优,因此只需要思考清楚局部最优是什么?如何推出全局最优就可以了。针对这道问题固定巧克力版的总面积,周长要尽可能小,那么每一小块正方形的边长要尽可能大,这样巧克力板的数量会尽可能少,周长和就会最短。

具体步骤

  • 初始化一个变量 res 用于存储总周长。
  • 使用一个循环,每次找到当前 n 的最大可能正方形边长 side,即 side = Math.floor(Math.sqrt(n))
  • 如果 side 的平方小于等于 n,则减去这个正方形的面积,并累加其周长(side * 4)到 res 中。
  • 重复上述步骤,直到 n 减为 0。

代码

function solution(n) {
    let res = 0;
    while (n > 0) {
        let side = Math.floor(Math.sqrt(n))
        if (side ** 2 <= n) {
            n -= side ** 2;
            res += side * 4
        }
    }
    return res;
}

最后利用豆包转成python提交,python代码如下:

import math

def solution(n):
    res = 0
    while n > 0:
        side = int(math.sqrt(n))  # 找到当前n的最大可能正方形边长
        if side ** 2 <= n:
            n -= side ** 2  # 减去这个正方形的面积
            res += side * 4  # 累加其周长到res中
    return res

def main():
    print(solution(11) == 20)
    print(solution(13) == 20)
    print(solution(25) == 20)

if __name__ == "__main__":
    main()

image.png

算法复杂度分析
1、时间复杂度分析
在 solution 函数中,主要的操作是找到当前 n 的最大可能正方形边长 side,即 side = int(math.sqrt(n))。每次循环中,n 会减去一个正方形的面积 side ** 2,直到 n 减为 0。由于 side 是 n 的平方根,每次循环 n 至少会减去 side ** 2,因此,循环的次数大约是 O(sqrt(n))。而每次循环中计算 side 的时间复杂度是 O(1)。因此,总的时间复杂度是 O(sqrt(n))
2、空间复杂度分析
主要变量有ressideres用于存储总周长,占用常数空间 O(1)side用于存储当前正方形的边长,占用常数空间 O(1)。此外,除了输入参数 n 外,函数中没有使用额外的空间。因此,总的空间复杂度是 O(1)