【问题标题】:General Fibonacci, why is it overflowing?斐波那契将军,为什么会溢出?
【发布时间】:2017-10-18 06:59:10
【问题描述】:

我正在尝试创建一个通用的斐波那契数列,其中起始值可以是可变的,具体取决于用户想要什么。例如,它可以从 3、6 或 10、21 或用户想要的任何值开始,而不是像通常那样从值 0、1 或 1、1 开始。然后我们想要获得该系列的第 n 个值。

我尝试了 a = 10 和 b = 21 的代码,我想要一个很大的值,但它不起作用。所以我开始检查问题出在哪里。使用这些起始值:对于 n = 37、38、39,输出应分别为 405812042、656617677、1062429719。当我为值 n = 37 和 n = 38 运行代码时,两个答案都是正确的。但是,当我尝试 39 时,得到的值是:62429712。

这是我的代码:

#include <stdio.h>

int main(void)
{
  unsigned long long a, b, hn, value;
  int scenarios;

  scanf("%d", &scenarios);

  for (int i = 0; i < scenarios; i++){
    scanf("%lld%lld%lld", &a, &b, &hn);
    if (hn == 1)
      value = a;
    else if (hn == 2)
      value = b;
    else{
      for (int j = 3; j <= hn; j++){
        value = a + b;
        a = b;
        b = value;
      }
    //value %= 1000000007;
    }
    printf("%lld\n", value);
  }


}

编辑:根据问题规范,答案应该是模块 1000000007。如果我得到第 514 个值,我得到的输出是 2903631044495864380,老实说,我不知道如何验证这个值。如果我执行 2903631044495864380 mod 1000000007,我的答案是 170447212,但根据问题,这个答案应该是 859861000。知道如何验证这一点吗?

【问题讨论】:

  • %llds 应该是 %llus
  • 无法重现:ideone.com/aJCFKc 虽然如前所述,为 unsigned long long 指定的格式不是 lld,但代码仍按预期工作
  • 一些unsigned long long的最大值在我的机器上只有2**64 - 1,因为它们有64位。
  • 您可能希望将arbitrary precision arithmeticGMPlib 一起使用
  • 总和模 N 等于(其每个分量模 N 的总和)模 N。所以,只需保持 ab 有效模 1000000007(我是否正确计算了零?) 并将它们相加并取模 100000007 的结果。这些值相加时不会超过 2^31-1,因此 32 位算术应该是可以的。

标签: c


【解决方案1】:

改变这个:

scanf("%lld%lld%lld", &a, &b, &hn);

到这里:

scanf("%llu%llu%llu", &a, &b, &hn);

改变这个:

printf("%lld\n", value);

到这里:

printf("%llu\n", value);

因为这些变量的类型为unsigned long long


编辑

看起来(根据您的编辑)您需要更改此内容:

value = a + b;

到这里:

value = (a + b) % 1000000007; 

【讨论】:

  • 谢谢!这解决了它,但显然我现在必须找到一个更有效的算法,只执行一半的子任务。不过还是谢谢 ;)
  • 首先你需要做对,然后优化@ch15,不客气!
【解决方案2】:

您误解了应该根据练习计算模数的点。

在进行取模之前不计算最终总和,而是对中间结果应用取模:

for (int j = 3; j <= hn; j++)
{
    value = (a + b) % 1000000007; // there
    a = b;
    b = value;
}

另外,按照@gsamaras 的建议,将您的扫描/打印格式更改为'%llu'

【讨论】:

  • 对,我在编辑 OP 后发现了这一点。不错的收获。
猜你喜欢
  • 2012-12-29
  • 2021-11-30
  • 2017-02-13
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 2012-05-06
相关资源
最近更新 更多