xy + yz + xz = N的不同解的数量

时间:2012-10-08 11:19:26

标签: number-theory

我一直在努力解决有关spoj的问题。 这是问题的链接。

http://www.spoj.pl/problems/TAP2012B/

根据我的解释,我需要找到方程xy + yz + xz = N的解的个数 其中n给我们。 X> = Y> = Z z可以为零。 但是x和y不能。 我尝试通过实现3 for for循环来解决这个问题(糟糕的方法)。 它给出了正确的答案,但它太慢了。 此外,其他人几乎没有时间解决它(0.00) 所以我确信这个问题有一个非常不同的方法。 对于N = 20, 不同解决方案的数量是5: (6,2,1) (5,4,0) (10,2,0) (4,2,2,) (20,1,0)

3 个答案:

答案 0 :(得分:2)

也许有一些基于数论的璀璨解决方案。但只需重新思考任务就可以降低算法的复杂性。

例如,我们不需要第三个循环,因为我们可以将z计算为(N - x*y)/(x+y)。如我们所知,我们不必每次都y一直x zN >= xy不是负面的,因此N = 9747 for x in range(1, N+1): max_y = min( N / x, x) for y in range(1, max_y+1): if (N - x*y) % (x+y) == 0: z = (N - x*y) / (x+y) if z <= y: print x,y,z

{{1}}

答案 1 :(得分:1)

你正朝着正确的方向靠近会有3个嵌套循环,但试着减少否。循环操作的次数....仔细地按照问题和条件.....

答案 2 :(得分:0)

你显然正在学习,所以如果你自己做所有事情本来会更好,但你现在有一个很好的解决方案来自akalenuk,我希望你也能从中学到一些东西。

如果你正在同时学习python,我会给你一个与akalenuk相同的解决方案,但这一次使用list comprehension这是一个非常有用的机制:

N = 10000

print [(x, y, z)
       for x in range(1, N+1)
       for y in range(1, min( N/x, x) + 1 )
       for z in [ (N - x*y) / (x+y) ] 
       if (N - x*y) % (x+y) == 0
       if z <= y]

重点在于修剪解决方案空间。上面的代码已经非常优化。您可以从以下内容开始:

N = 10000

print [(x, y, z)
       for x in range(1, N+1)
       for y in range(1, x+1 )
       for z in range(y+1) 
       if N == x*y + y*z + x*z]

这会持续很长时间。因此,优化的第一点可能是在y上添加条件:

N = 10000

print [(x, y, z)
       for x in range(1, N+1)
       for y in range(1, x+1 )
       if x*y <= N
       for z in range(y+1) 
       if N == x*y + y*z + x*z]

这已经大大减少了时间,因为非有希望的y z - 循环根本没有运行。然后,您注意到您实际上可以通过显式计算最大y来替换if语句,如akalenuk所做的那样:

N = 10000

print [(x, y, z)
       for x in range(1, N+1)
       for y in range(1, min(x, N/x) +1)
       for z in range(y+1) 
       if N == x*y + y*z + x*z]

这将再次加快速度。

在你学习的过程中,我建议你尝试所有这些,你自己,时间,并从中学习。 我还建议尝试和时间不同,类似的解决方案