【问题标题】:Last Digit in Sum of Fibonacci Series (m,n)斐波那契数列和的最后一位 (m,n)
【发布时间】:2019-09-09 15:39:11
【问题描述】:

我对找到从索引 m 到索引 n 的斐波那契数列项和的最后一位存有疑问(考虑起始项的索引为 0)。

我有很多不同的方法来解决这个问题。但是对于 ex m=2,n=82364572389 等,也需要通过很长的案例。但是当我尝试使用此算法时,我的一些测试用例通过了,但有些没有。

你能帮我看看我的代码有什么问题还是这个算法有问题。

还有如何用更好的方法解决这个问题。

#include <iostream>
using namespace std;

long long calc_fib(long long n) {

    n = (n+2)%60;
    int fib[n+1];
    fib[0]=0;
    fib[1]=1;
    int res = 1;
    for(int i = 2; i<=n;i++){
        fib[i] = (fib[i-1]%10 + fib[i-2]%10)%10;
        // res = res + fib[i];
    }
    // cout<<fib[n]<<"\n";
    if(fib[n] == 0){
        return 9;
    }
    return (fib[n]%10-1);
}

int main() {

long long n = 0,m;

std::cin >> m;

    std::cin >> n;

    std::cout << calc_fib(n)-calc_fib(m-1) << '\n';
    return 0;
}

测试用例

Test Case: 5 10
Correct Output: 6
My Output: -4

Test Case: 1 10000000
Correct Output: 5
My Output: 5

【问题讨论】:

  • int fib[n+1]; 不是有效的 C++。
  • int fib[n+1];undefined behavior
  • 当您说总和的最后一位时,您的意思是按小数点 n 的近似值,或者按字面意思将每个数字相加?
  • 您正在计算第 n 个数字的最后一位数字与 m-1:st 数字的最后一位数字之间的差异。这不是问题所在。
  • 解决这个问题的有趣方法是尝试从标准summation formula 推导多项式函数,方法是通过黄金比例的步进函数和反向步进偏差。请记住,斐波那契数列是黄金均值的理想化——因此需要实现一些整数魔法,而斐波那契数列在很大程度上取决于它的基数。 `Fib(3, item=4) != Fib(6, item =4)

标签: c++ fibonacci


【解决方案1】:

您需要更改算法。

第一件事:不要递归计算值。就运行时而言,这非常昂贵。从 f(0) 开始,然后是 f(1),然后使用最后存储的两个值计算 f(2)。继续这样。只存储最后两个值。

第二:意识到完全存储 f(n) 是没有意义的。您可以只保留 unitstens(十位不是必需的,但有助于调试)。这看起来像: 1、1、2、3、5、8、13、21、34、55、89、44、33

注意 89+44 得到 133,它以 33 结尾,就像 89+144 得到 233,它也以 33 结尾。

将两者结合后,您将需要一个循环,计数器会说 82364572389,并执行简单的加法/模运算。它应该在几分钟内结束,顶部。

在那里,您可以开始考虑进一步的优化(有)。不过以上两个应该就够了。

另外,来自 cmets,并重新阅读问题:

calc_fib(n) - calc_fib(m-1)

是错误的,因为它可能会产生负数。而最后一位数字必须是正数。您可能需要采取这种差异diff,然后:

diff = (diff + 10) % 10;

让它变得积极。

最后,为什么是 9 ?为什么在return (fib[n]%10-1); 中为-1?这似乎将所有内容都抵消了一个,但减法中的 -1 都抵消了。

【讨论】:

  • 问题是关于从某个开始索引到某个结束索引的斐波那契值的总和。尽管您的所有评论都很有用,但显示的一个失败的测试用例由于不相关的原因而失败。
  • 这很好。 n = (n+2)%60;对OP的一点暗示比问题状态还多。但是,calc_fib(n) - calc_fib(m-1) 是一个错误
【解决方案2】:

继续在for 循环内移动总和,如下所示:

#include <iostream>
using namespace std;

int main() {
    unsigned int i, j, n, v, sum;

    cout << "Fibonacci numbers from 1 to 10000: " << endl;

    cout << '1' << endl;
    cout << '1' << endl;
    cout << '2' << endl;
    for (i = j = v = 1, n = 2, sum = 4; n + j < 10000; sum += v) {
        v = n + j; i = j; j = n; n = v;
        cout << v << endl;
    }

    cout << "Sum of Fibonacci numbers from 1 to 10000: " << sum << endl;

    return 0;
}

添加了测试代码链接 [http://codepad.org/8CHIepXe]

【讨论】:

  • 为什么要将cout 放在循环增量表达式中?
  • sum += v 打算在那个地方:代码已被编辑。
猜你喜欢
  • 2017-01-29
  • 2019-05-29
  • 2020-09-04
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
相关资源
最近更新 更多