为什么以下两个“阶乘尾随零”的解决方案不相同?

时间:2016-02-29 06:56:23

标签: c algorithm

我正在OJ网站上处理Factorial Trailing Zeroes问题。我搜索了问题并提出了一些解决方案:

int solution1(int n) {
  int result = 0;
  while (n > 0) {
    result += n /= 5;
  }
  return result;
}

int solution2(int n) {
  int result = 0;
  for (int i = 5;n >= i; i *= 5) {
    result += n/i;
  }
  return result;
}

尽管实施细节,我认为基本原理是相同的,可以找到here。因此我假设这两种解决方案是等价的。但是当我提交它们时,事实证明,当n = 1808548329时,解决方案2通过了502个测试用例中的500个并得到了错误的答案(结果= 452137080),而解决方案1得到了正确答案(结果= 452137076)。

现在我很困惑这里出错了。谁能告诉我为什么上述两种解决方案不相同?为什么solution1是正确的,solution2是错的?

1 个答案:

答案 0 :(得分:8)

因为void foo(List<? extends X<?>> arg) { ... } 可能会溢出。当它溢出时,您不再与i *= 5进行正确的比较。

说n = 1808548329。这是发生的事情:

n

我用以下内容生成了上述内容:

             i              n      correct i
   -----------     ----------   ------------
             5     1808548329              5
            25     1808548329             25
           125     1808548329            125
           625     1808548329            625
          3125     1808548329           3125
         15625     1808548329          15625
         78125     1808548329          78125
        390625     1808548329         390625
       1953125     1808548329        1953125
       9765625     1808548329        9765625
      48828125     1808548329       48828125
     244140625     1808548329      244140625
    1220703125     1808548329     1220703125
    1808548329     1808548329     6103515625 # i overflows here; loop should stop
     452807053     1808548329    30517578125
   -2030932031     1808548329   152587890625
   -1564725563     1808548329   762939453125
     766306777     1808548329  3814697265625
    -463433411     1808548329 19073486328125
    1977800241     1808548329 95367431640625

(在原始代码中,某些#include <stdio.h> int main() { int n = 1808548329; int i = 1; long long l = 1; do { i *= 5; l *= 5; printf("%14d %14d %14lld\n", i, n, l); } while (n >= i); return 0; } 值将为负值,只是为了让情况更加混乱。我没有包含n/i列;这样做可能很有趣。)