斐波纳契将军,为什么会溢出?

时间:2017-10-18 06:59:10

标签: c

我正在尝试创建一个普通的斐波纳契系列,其中起始值可以变化,具体取决于用户想要的内容。例如,不像通常那样从值0,1或1,1开始,而是以3,6或10,21或用户想要的任何东西开始。然后我们想获得该系列的第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.知道如何验证这个吗?

2 个答案:

答案 0 :(得分:4)

改变这个:

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; 

答案 1 :(得分:2)

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

在执行模数之前,您不计算结束总和,但是您将模数应用于中间结果:

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

另外,将您的扫描/打印格式更改为'%llu',正如@gsamaras建议的那样。