首页 > 解决方案 > 有多少种方法可以获得总计为 x 的连续整数之和?

问题描述

如何以编程方式解决这些问题:

有多少种不同的写法:

  • a) 2021 是连续整数的总和?
  • b) x 作为连续整数的总和?

标签: mathpermutation

解决方案


假设数字的顺序并不重要,有一些8518741657943308344041302580996941768179250799方法可以写成2021正整数的总和。它被称为分区号。没有一个简单的公式,但是有一个递归关系可以计算很多值。

该函数在 Python 的sympy中实现:

from sympy import partition

print(partition(2021))

现在,对于新问题,写2021为连续整数之和:n + n+1 + ... + m-1 + m = 2021。首先请注意,负值n不会添加任何有趣的东西。当 时n < -m,总和显然是负数。否则,负值只会“吃掉”相应的正值,并且您得到与正解相同的总和。

1从到的数字之和mtri(m)=m*(m+1)/2, (三角数)。n从到的数字之和mtri(m)-tri(n-1)。这些方程可以通过SAT/SMT 求解器(例如Z3 )求解:

from z3 import Int, Solver, And, Or, sat

s = Solver()
m = Int('m')
n = Int('n')
s.add(And(n > 0, n < 2022))
s.add(n <= m)
s.add(And(m > 0, m < 2022))
s.add(m * (m + 1) - n * (n - 1) == 2021 * 2)
while s.check() == sat:
    mi = s.model()[m].as_long()
    ni = s.model()[n].as_long()
    if ni > mi - 30:
        print("+".join([str(i) for i in range(ni, mi + 1)]), end="=")
    else:
        print("+".join([str(i) for i in range(ni, ni + 6)]), "+...+",
              "+".join([str(i) for i in range(mi - 4, mi + 1)]), end="=", sep="")
    print(sum([i for i in range(ni, mi + 1)]))
    s.add(Or(m != mi, n != ni))

输出:

26+27+28+29+30+...+64+65+66+67+68=2021
20+21+22+23+24+...+62+63+64+65+66=2021
1010+1011=2021
2021=2021

1-n因此,对于 2021 年,有 4 个正解(以及 4 个相应的解,其中包括从到的负数m)。


推荐阅读