为Project euler#25改善蛮力解决方案

时间:2014-02-13 05:08:38

标签: c++ performance c++11 c++98

我最近偶然发现了这个项目欧拉问题#25:

  

第12个学期F12是第一个包含三位数的术语。

     

Fibonacci序列中包含1000位数的第一项是什么?

我只知道C ++ 98而没有其他编程语言。我试图解决它,进行更改以获得对c ++ 11的支持。

工作:

#include <iostream>
#include<cstdio>
long len(long);              //finding length
int main()
{
    /* Ques: What is the first term in fibonacci series to contain 1000 digits? */

    int ctr=2;
    unsigned long first, second, third, n;
    first=1;
    second=1;
    std::cout<<"\t **Project EULER Question 25**\n\n";
    for(int i=2;;++i)
    {
        third=first+second;
        //  cout<<" "<<third;
        int x=len(third);
        //  cout<<" Length: "<<x;
        //  cout<<"\n";

        first=second;
        second=third;
        ctr++;
            if(x>1000)        // for small values, program works properly
        {
            std::cout<< " THE ANSWER: "<< ctr;
            system("pause");
            break;
        }

    }
}

long len(long num)
{


    int ctr=1;

    while(num!=0)
    {
        num=num/10;
                if(num!=0)
            {
                ctr++;
            }
    }

    return(ctr);
}

我知道这是蛮力,但我可以让它更有效率,以便我得到答案吗?

非常感谢任何帮助。

修改

按照PaulMcKenzie的建议使用Binet的公式并将其实现为:

#define phi (1+sqrt(5))/2
int main(void)
{
   float n= ((999 + (1/2)*log10(5))/(log10(phi)));     //Line 1
   cout<<"Number is  : "<<n;
   return 0;
}

输出:4780.187012

将上面的第1行更改为:

float n= ((999 + log10(sqrt(5)))/(log10(phi)));

输出:4781.859375

这可能是错误吗?

1 个答案:

答案 0 :(得分:2)

unsigned long根本无法保存1000位数字。因此,当firstsecond达到unsigned long限制时,您的代码会出现溢出。如果你想要一个强力解决方案 - 考虑使用类似biginteger library的东西或自己写一个。