【问题标题】:Find four factors of a number such that their product is maximum and their sum is the original number找出一个数的四个因数,使得它们的乘积最大并且它们的总和是原始数
【发布时间】:2020-03-30 16:14:38
【问题描述】:

给定测试用例数 T 和一个整数 N,你需要找到四个整数 A,B,C,D ,它们都是 N(A|N,B|N,C|N, D|N),N=A+B+C+D。目标是最大化 A * B * C * D。如果无法找到这四个因素,只需返回 -1。

问题的输入格式是:
第一行包含一个整数T(1 接下来的 T 行中的每一行都包含一个整数 N(1

这个问题在递归类别下的 Hackerearth 上,但我无法理解社论中的算法(编辑链接:-https://www.hackerearth.com/practice/basic-programming/recursion/recursion-and-backtracking/practice-problems/algorithm/divide-number-a410603f/editorial/)。

在社论中,它已使用单位分数解决,但我无法理解算法(如果您无法打开上述链接,我在下面提供了社论,我无法理解标有***的点)。蛮力解决方案导致 TLE(超出时间限制)。请提供使用 DFS 或回溯的算法或伪代码。

我的蛮力方法:- 计算 O(sqrt(n)) 中数字“n”的因数并将它们存储在一个数组中,然后使用四个 for 循环遍历数组以获取 A、B、C、D .但是对于 T(1

社论(如果您无法打开以上链接):-

考虑方程 N = A+B+C+D ,如果我们将方程除以 N ,我们得到 1 = 1/A' + 1/B' + 1/C' + 1/D' ,这里是 A ',B',C',D'都是整数,因为A,B,C,D是N的因数。

所以原来的问题等于把1分成四个单位分数。

我们可以从大到小枚举单位分数。

***如果我们需要将X分成Y个单位分数,而最后一个单位分数是1/Z,我们可以枚举1/Z和X/Y之间的单位分数(因为我们是在枚举剩余的最大分数) ,并递归求解。

*** 找到 1 = 1/A' + 1/B' + 1/C' + 1/D' 的所有解后(如果数字按顺序大约有 20 个解),我们可以在每个解中枚举它们测试用例。如果A',B',C',D'都是N的因数,我们可以用这个解来更新答案。

时间复杂度:O(T),其中 T 是测试用例的数量。

【问题讨论】:

    标签: algorithm recursion depth-first-search number-theory


    【解决方案1】:

    ***如果我们需要将X分成Y个单位分数,而最后一个单位分数是1/Z,我们可以枚举1/Z和X/Y之间的单位分数(因为我们是在枚举剩余的最大分数) ,并递归求解。

    答案:我们正在尝试找出 1 = 1/A + 1/B + 1/C + 1/D 的所有组合。最初,我们有 X=1 和 Y=4,我们枚举 A 作为最大因子,它应该不小于 X/Y = 1/4。因为这是第一个元素,所以没有最后一个分数 1/Z。假设我们选择 A=3,那么最后一个分数 1/Z 是 1/A=1/3,X=1-1/3=2/3,Y=3。现在我们从 [X/Y, 1/Z] = [2/9, 1/3] 中选择 1/B。为接下来的步骤做同样的事情。

    *** 找到 1 = 1/A' + 1/B' + 1/C' + 1/D' 的所有解后(如果数字按顺序,大约有 20 个解),我们可以在每个解中枚举它们测试用例。如果A',B',C',D'都是N的因数,我们可以用这个解来更新答案。

    答案:因为1/A应该不小于1/4,所以A只能是2、3、4。如果A==4,那么A=B=C=D,只有一种解。如果 A==3, [X/Y, 1/Z] = [2/9, 1/3],那么 B 只能是 3 或 4,如果 B ==4,那么下一轮 C 应该是 4 其中 [ X/Y, 1/Z] = [5/24, 1/4];如果 B=3,则 C 可能是 4,5,6,因为 [X/Y, 1/Z]=[1/6,1/3]。如果 A==2,[X/Y, 1/Z] = [1/6, 1/2],则 B 可能是 3,4,5,6。您可以使用代码进行其余计算,感觉我们可以切断许多搜索分支。 (忽略我的枚举顺序,你应该从A=2开始。)

    【讨论】:

    • 谢谢,我现在明白了。我也写了代码,它正在工作。
    • @dark_prince 一个技巧,使用 N/B 而不是 1/B。这将使您的计算更容易避免常见的分数,因为 N 可以除以 B。
    【解决方案2】:

    可以通过仅使用 3 个 for 循环并应用二进制搜索来查找第四个数字来提高代码的时间复杂度,因为二进制搜索的时间复杂度是 log(n)。 时间复杂度 = O(n^3*(log(n)) 并根据 问题的限制它应该能够通过所有的测试用例。

    【讨论】:

    • 我也使用了三个循环,不需要使用二分搜索(第四个数字 = N-A-B-C)。实际上因素的总数大约是 O(sqrt(3*n))(math.stackexchange.com/questions/1699330/…) 所以使用三个循环意味着 O(nsqrt(n)) 并且对于 T 测试用例它将是O(Tnsqrt(n)) 将超过时间限制
    • 参考这个:link text
    • hackerearth 问题与上面链接中提到的问题略有不同,geeks for geeks question 中没有测试用例,whixh 导致hackerearth 中的 TLE,但有效的方法(最后一个)是最好的解决方案(时间复杂度 O(log(n)),它给出了 T 个测试用例的时间复杂度(T*log(n)),感谢提供 gfg 链接。
    • 我认为我们不需要像更好的方法部分(第二个)中提到的那样对第四个数字使用二进制搜索,因为第四个数字 = N-A-B-C,我们只需要检查它是否除以 N 或不是。
    猜你喜欢
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2019-05-03
    相关资源
    最近更新 更多