昨天晚上看到《怎样解题:数学竞赛攻关宝典(第2版)》第7章“数论”7.4节“丢番图方程”的如下习题:

今天早上 7:15 从家里出发,步行去上班,7:50 到达单位(其间还在单位食堂吃了早餐)。路上反正没事做,闲着也是闲着,就思考这道题,进行心算。以下是解题过程:

  1. 首先思考两变量的情况,即:
  2. 因为 是无理数, a = b 是不可能的。
  3. 心算化简:
    • (a + 1)(b + 1) = 2ab
    • a + b + 1 = ab
    • a + 1= (a - 1)b
    • b = (a + 1) / (a - 1)
  4. 很显然,(a, b) = (2, 3) 是一组解。
  5. 既然两变量的情况有解,三变量的原题也可能有解。
  6. 先固定 c = 2,得到
  7. 再试试 c = 3,得到
  8. 继续试 c = 4,得到
  9. 嗯,还是 c = 3 的情况最简单。
  10. 类似地心算化简:
    • 2(a + 1)(b + 1) = 3ab
    • 2a + 2b + 2 = ab
    • 2a + 2= (a - 2)b
    • b = 2(a + 1) / (a - 2)
  11. 显然,原方程有以下解:
    • (a,b,c) = (3,8,3)
    • (a,b,c) = (4,5,3)
    • (a,b,c) = (5,4,3)
    • (a,b,c) = (8,3,3)

此时,我到达单位了。停止思考,写了下这篇文章。

在单位,继续,这次用笔算 c = 2 的情况,得到以下解:

  • (a,b,c) = (4,15,2)
  • (a,b,c) = (5,9,2)
  • (a,b,c) = (6,7,2)

然后,用 C 语言写了一个非常简单的程序:

#include <stdio.h>

int main(void)
{
  const int n = 1000;
  for (int a = 2; a <= n; a++)
    for (int b = a; b <= n; b++)
      for (int c = b; c <= n; c++)
        if (2L*a*b*c == (a+1L)*(b+1)*(c+1))
          printf("%d,%d,%d\n", a, b, c);
}

运行结果:

2,4,15
2,5,9
2,6,7
3,3,8
3,4,5

现在我们来证明这些就是原方程的全部解。

不失一般性,假设 2 ≤ a ≤ b ≤ c,(请读者自己思考 a 为什么不能小于 2)则:

也就是说,a = 2 或 a = 3。

当 a = 2 时,我们有:

也就是说,当 a = 2 时,b 只能是 2, 3, 4, 5, 6 中的一个,这就唯一确定了 c 。

当 a = 3 时,同样的论证过程可以得出 b 只能是 3 或 4,这也唯一确定了 c 。

证毕。