【问题标题】:Cracking The Coding Interview - Print all positive integer solutions to the equationCracking The Coding Interview - 打印方程的所有正整数解
【发布时间】:2020-04-24 11:38:26
【问题描述】:

在《Cracking The Coding Interview》一书中

有一个例子:

打印方程的所有正整数解

a^3 + b^3 = c^3 + d^3

其中a、b、c 和d 是介于1 和1000 之间的整数。

Image

书中说“只有一个人可以工作”,但我不明白。

正如我所见,只要所有这些变量都相等,它就会起作用

例子:

a = 1, b = 1, c = 1, d = 1
a = 2, b = 2, c = 2, d = 2
a = 3, b = 3, c = 3, d = 3

【问题讨论】:

  • 是的,你是对的,肯定有多种解决方案。你确定这些都是书中的要求吗?还是only one could work 的上下文真的是你的意思?
  • 我认为您是在询问书中的一句话“只有一个人可以工作”,但是如果没有上下文,很难做到这一点。显然,这并不意味着只有一种解决方案(或者这是非常错误的),因为有很多解决方案。
  • 我找到了这本书,当你找到解决方案时,你错过了关于打破 d 循环的上下文,因为只有一个 d 值可以工作(对于给定的 @987654333 @、b、c)。
  • 如果我们排除琐碎的解决方案,即如果我们需要a != c, a !=d, b != c, b != d,该怎么办?
  • 关于 d 循环,似乎没有必要迭代直到找到 d 值。包含所有 d^3 解决方案的简单哈希图会更快(检查 a^3 + b^3 - c^3)

标签: algorithm


【解决方案1】:

作为一种猜测(问题是什么?)让我展示如何解决这些问题(以便在采访中展示);你说的很对,有很多明显的解决方案,比如

  1**3 + 1**3 = 1**3 + 1**3
  1**3 + 2**3 = 2**3 + 1**3

我们所要做的就是设置a = c 和b = d 或a = d 和b = c。像下面这样的非平凡解决方案呢?

   1**3 +  12**3 =   9**3 +  10**3
  84**3 + 280**3 = 217**3 + 231**3

请注意,我们可以交换 a 和 b 或 / 和 c 和 d,并有一个 衍生 解决方案,例如

  12**3 + 1**3 = 10**3 + 9**3

为了排除它们,我们假设 a <= b、c <= d 和 a < c

带有嵌套循环的幼稚代码(书中提到)持续时间太长:我们需要计算 1000 * 1000 * 1000 * 1000 = 1e12 操作。 然而,我们可以使用 meet in the middle 技术,并在几分之一秒内得到结果(删除了 两个 最里面的循环):

  1. 计算所有 a**3 + b**3 值(仅 1000 * 1000 = 1e6 操作 - 上限)
  2. 将它们分组
  3. 过滤掉感兴趣的组

C# 代码:

  Dictionary<long, List<(long, long)>> cubes = new Dictionary<long, List<(long, long)>>();

  for (long a = 1; a < 1000; ++a) {
    long a3 = a * a * a;

    for (long b = a; b < 1000; ++b) {
      long key = b * b * b + a3;

      if (cubes.TryGetValue(key, out var list))
        list.Add((a, b));
      else
        cubes.Add(key, new List<(long, long)>() { (a, b) });
    }
  }        

现在我们有cubes 是这样的

  {2, {(1, 1)}} // group with one (a, b) pair
  {9, {(1, 2)}} // another group with one (a, b) pair
   ...
  {1729, {(1, 12), (9, 10)}} // <- the group we are looking for!
   ...

查询组的时间:

var report = string.Join(Environment.NewLine, cubes
  .Where(pair => pair.Value.Count >= 2)
  .Select(pair => $"{string.Join(" = ", pair.Value.Select(t => $"{t.Item1}**3 + {t.Item2}**3"))}"));

Console.Write(report);

结果:

1**3 + 12**3 = 9**3 + 10**3
1**3 + 103**3 = 64**3 + 94**3
1**3 + 150**3 = 73**3 + 144**3
1**3 + 249**3 = 135**3 + 235**3
... 
22**3 + 986**3 = 180**3 + 984**3 = 692**3 + 856**3
...
802**3 + 987**3 = 883**3 + 924**3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2019-07-12
    • 2011-11-11
    相关资源
    最近更新 更多