算法:分解一个整数 X 以获得尽可能多的不同正整数 (Y1...Yk) 使得 (Y1+1)(Y2+1)...(Yk+1) = X

Posted

技术标签:

【中文标题】算法:分解一个整数 X 以获得尽可能多的不同正整数 (Y1...Yk) 使得 (Y1+1)(Y2+1)...(Yk+1) = X【英文标题】:Algorithm: Factorize a integer X to get as many distinct positive integers(Y1...Yk) as possible so that (Y1+1)(Y2+1)...(Yk+1) = X 【发布时间】:2017-10-09 20:50:35 【问题描述】:

我最近在 open.kattis.com 遇到了一个算法问题。 问题的链接是https://open.kattis.com/problems/listgame2。 基本上,这是一个要求玩家分解整数 X (10^3 distinct 正整数 (Y1,...,Yk) 尽可能使得 (Y1+1)(Y2+1)⋯(Yk+1) = X.

我已经想出了一个使用 Python3 的解决方案,它确实通过了几个测试用例,但其中一个失败了:MyStatus

我的代码是:

def minFactor(n, start):
    maxFactor = round(n**0.5)
    for i in range(start, maxFactor+1):
        if n % i == 0:
            return i
    return n

def distinctFactors(n):
    curMaxFactor = 1
    factors = []

    while n > 1:
        curMaxFactor = minFactor(n, curMaxFactor+1)
        n //= curMaxFactor
        factors.append(curMaxFactor)

    # This is for the situation where the given number is the square of a prime number
    # For example, when the input is 4, the returned factors would be [2,2] instead of [4]
    # The if statement below are used to fix this flaw
    # And since the question only requires the length of the result, deleting the last factor when repeat do works in my opinion
    if factors[-1] in factors[:-1]:
        del factors[-1]

    return factors

num = int(input())
print(len(distinctFactors(num)))

具体来说,我在上面代码中的想法很简单。例如,当给定输入为 36 时,我运行 minFactor 函数发现 36 的最小因子为 2(在这种情况下忽略 1)。然后,我通过执行 36/2 得到 18 并调用 minFactor(18,3),因为 2 不再不同,所以我开始通过 3 找到 18 的最小因子。显然它是 3,所以我通过执行 18 得到 6 /3 在函数 distinctFactors 中并调用 minFactor(6,4),因为 4 小于 sqrt(6) 或 6**0.5 所以 6 本身将被返回,我最终得到列表因子为 [2,3,6],这是正确的。

我已经检查了我的代码和算法几个小时,但我仍然无法弄清楚为什么我没有通过测试用例,谁能帮助我解决我的困境吗?等待回复。

【问题讨论】:

不能保证总是选择最小的因子是最优的(甚至不能保证它会产生一个没有重复因子的有效解决方案)。 @user2357112,但我认为从最小的因素考虑可以给我最长的列表因素......我认为每次我想获得尽可能多的东西时,我都会从最小的情况开始。 ..所以你能给我一个例子或详细解释你的想法吗,谢谢~ 最大的因子集由X质因式分解 给出。然后对于每个重复的因子,计算最大的非重复集。例如24 = 2^3 * 3 = 2 * 4 * 3。这可以使用动态规划来完成 @meowgoesthedog:也没有理由期望它会产生最佳集合。例如,它在 Peter de Rivaz 的示例中失败。 【参考方案1】:

考虑数字2**6.11**5

您的算法将找到 5 个因素:

2
2**2
2**3
11
11**2
(11**2 this will be discarded as it is a repeat)

一个 6 长的答案是:

2
2**2
11
11**2
2*11
2**2*11

【讨论】:

哦,非常感谢你的反例!我现在知道我的错误了。当我开始思考这个问题时,似乎我一开始就错了:(顺便说一句,你能给我一些关于正确方向的提示吗?或者你将如何处理这个问题?再次感谢~

以上是关于算法:分解一个整数 X 以获得尽可能多的不同正整数 (Y1...Yk) 使得 (Y1+1)(Y2+1)...(Yk+1) = X的主要内容,如果未能解决你的问题,请参考以下文章

算法---分解质因数

算法---分解质因数

算法课最多约数问题

(蓝桥杯)试题 算法训练 加法分解

质因数分解

C 或 C++:用于分解整数的库?