无法解决Project Euler问题#2的问题

时间:2009-11-30 06:38:06

标签: c++

我正在尝试通过解决一些Project Euler问题来学习C ++的基础知识。我已经做到了......#2。

  

Fibonacci中的每个新术语   序列是通过添加   前两个任期。从1开始   2,前10个术语将是:

     

1,2,3,5,8,13,21,34,55,89,......

     

找出所有偶数值的总和   序列中没有的术语   超过四百万。

我的逻辑:

0, 1, 1, 2, 3, 5
x  y  z
   x  y  z
      x  y  z
         x  y  z

以上是循环:

x + y = z
x = y
y = z

我的代码:

#include <iostream.h>

using namespace std;

int main()
{
    int x = 0;
    int y = 1;
    int z;
    int sum;

    for(y = 1; y <= 4000000; y++) {

          z = x + y;
          x = y;
          y = z;
            if(y % 2 == 0) {
                 sum += y;
                 }
            }
    cout << sum;
    cin.get();
}

输出4613788 但是,正确的答案是4613732

我不知道出了什么问题。 = /

15 个答案:

答案 0 :(得分:19)

您使用y作为循环变量和序列中的第二个术语。

你的意思是:

int x = 0;
int y = 1;
int z;
int sum = 0;

do {
    z = x + y;
    x = y;
    y = z;
    if (y % 2 == 0) sum += y;
} while (y <= 4000000);

注意您也应该初始化sum

答案 1 :(得分:15)

为了提高速度,请注意序列是偶数奇数(重复),偶数奇数。

您无需测试每个数字即可知道它是偶数还是奇数。只需添加第三个数字。

答案 2 :(得分:5)

你没有将总和初始化为零。

答案 3 :(得分:3)

for循环代码块应该类似于

while(y <= 4000000) {
    z = x + y;
    x = y;
    y = z;
    if(y % 2 == 0) {
        sum += y;
    }
}

基本上,你不应该增加y。

答案 4 :(得分:3)

以下是我们如何在最小数量的循环中完成的工作。如果我们根据前两个数字写出Fibonacci系列,那就是:

a,b,(a + b),(a + 2b),(2a+3b),(3a + 5b),(5a + 8b),(8a+13b),(13a + 21b),(21a + 34b),(34a+55b) ....

在上面的系列中,a为1,b为2,突出显示的数字为偶数。在Fibonacci系列中,每三个数字是偶数,序列是EVEN-ODD-ODD-EVEN-。因此,如果我们写偶数是这个系列,那就是:

b, (2a+3b), (8a+13b), (34a+55b), (144a+233b)...

如果我们在本系列中观察到模式,则coefficient_of_next_a4*(coefficient_of_current_a)+(coefficient_of_previous_a)coefficient_of_next_b(coefficient_of_current_a)+(coefficient_of_current_b)+(coefficient_of_next_a)

Python代码:

# Start sum with first event number
sum = 2

# Values of first two Fibonacci numbers
a = 1
b = 2

# Previous coefficient of a
prev_coef_a = 0

# Current coefficient of a and b
coef_a = 2
coef_b = 3

while ((coef_a*a)+(coef_b*b)) <= 4000000:
    print(((coef_a*a)+(coef_b*b)))
    sum += ((coef_a*a)+(coef_b*b))

    # Coefficient of a for next number
    next_coef_a = (coef_a*4)+prev_coef_a
    prev_coef_a = coef_a
    # Coefficient of b for next number
    coef_b = coef_a+coef_b+next_coef_a
    coef_a = next_coef_a

print('Sum: {}'.format(sum))

输出是:

8
34
144
610
2584
10946
46368
196418
832040
3524578
Sum: 4613732

答案 5 :(得分:1)

这是一种在O(log(N))中解决这个问题的方法 - 时间与较慢的O(N)实现(O(log(N))来自需要使用pow()函数)

首先,您需要能够在O(log(N))时间内计算第N个Fibonacci数:

double Fib(double N)
{
    double Fn = (pow(PHI, N) - pow(PSI, N)) / sqrt(5);

    return floor(Fn);
}

其中PHI = 1.6180339 ...且PSI = -0.61803398 ...(查看wiki了解更多信息)

其次,您需要计算最接近目标限制的索引(问题2的情况是4,000,000):

double nFib(double F)
{
    double nFib = log((double)F * sqrt(5) + 0.5) / log(PHI);

    return floor(nFib);
}

第三,您将使用B&amp; Q身份#25(更多信息here)来计算偶数斐波纳契数的总和:

double bqIdentity25(double N)
{
    return (Fib(3*floor(N) + 2) - 1) / 2;
}

最后,计算总和:

double limit = 4000000;
double nearestIndex = nFib(limit);
double sum = bqIdentity25(nearestIndex / 3);

我们只需要每三个元素来计算偶数Fibonacci数的总和。

希望这有帮助! 将

答案 6 :(得分:1)

    //fibonacci sequence
    #include <iostream>
    #include <vector>

    using namespace std;

    int main()
    {
        vector<unsigned long int> list;
        list.clear();
        list.push_back(1);
        list.push_back(2);
        cout<<"1\n2\n";
        unsigned long int last;
        unsigned long int prev;
        do{
            last=list.at(list.size()-1);
            prev=list.at(list.size()-2);
            list.push_back(last+prev);
            cout << list.at(list.size()-1)<<'\n';
        }while(last<4000000);
        unsigned long int sum=0;
        for(int a=0;a<list.size();a++)
        {
            if(list.at(a)%2==0)
            {
                sum+=list.at(a);
            }
        }
        cout <<'\n'<<sum<<'\n';
        return 0;
    }

答案 7 :(得分:1)

显示每个Fibonacci序列号并选择偶数序列号, 最后给出了偶数的总和。

 #include <stdio.h>
 #include <math.h>
 #include <time.h>
    //project euler
    //problem# 2
int main()
{
    long int a = 0;
    long int b = 1;
    long int sum = 0;
    long int f = 0;
    long int t = 1;
    long int d = 1;

  while (f <= 4000000){
  f = a + b;
  printf("   %2d. number is %7d",d,f);
  d++;
  a = b;
  b = f;
    if (f % 2 == 0){
        sum += f;
        printf("\t\t%2d. target is %7d",t,f);
        t++;
    }
  printf("\n\n");
  printf("--------------------------------------------------------------------------------");
  }
printf("\n\n\t\t\t\t\tSum of targets is %d\n\n\n", sum);
printf("--------------------------------------------------------------------------------\n");
printf("Press any key to continue...\n");
getchar();
}

答案 8 :(得分:1)

perl -e '$a,$b=(0,1);while($a<4*10**6){$a%2==0and$sum+=$a;$a+=$b;$c=$a;$a=$b;$b=$c;}print"$sum\n"'

我最近开始研究Perl的神秘艺术......(爱它!)

但我会解释它...我们需要三个变量,我们将移动我们需要的2个值,以便找到序列中的下一步(将被分配给第3个var,如{{1} })。 $c=$a;$a=$b;$b=$c;$a被预先声明,因为我们知道fibo从它们开始($b)。只要我们在我们的boologic中使用的变量小于4mil($a,$b=(0,1)),我们就会从那里得到一个循环滚动。在每次迭代中,我们检查带有模数的偶数(while($a<4*10**6))和加上等于我们的$ sum变量($a%2==0)。在对变量进行混洗之后(如前所述),它只是“打印并完成”。

我知道你想用C / C ++做这个(perl是用C语言编写的),但我只是搞乱了Perl中的euler问题,并认为这可能提供了洞察力。

如果它根本没有帮助(除了不是正确的语言),请告诉我如何改进我的答案,以便我将来可以提供更好的答案。最重要的是,祝你有个美好的一天!

高尔夫球吗?

答案 9 :(得分:0)

尝试为问题添加一些帮助。以下程序显示用户输入的给定系列长度的所有偶数斐波那契序列号。

         #include<iostream.h>
         #include<conio.h>
          class fibonacci
          {
               int input;
                        public:
                                  void series();
          };
               void fibonacci::series()
                    {
                           cout<<"enter the value";
                           cin>>input;
                           int initial=0;
                           int initial1=1;
                     for(int loop=0;loop<input;loop++)
                          { 
                             int initial2;
                             initial2=initial1+initial;
                             if(initial2%2==0)
                             {cout<<initial2<<"\t";}
                             initial=initial1;
                             initial1=initial2;
                             }
                       }
                      void main()
                                  {
                                      fibonacci a;
                                      a.series();
                                      getch();
                                   }

答案 10 :(得分:0)

以下是如何在Swift中执行此操作:

/** Calculate the next even fibonacci number within a limit.

Methodology:
1) Fibonacci numbers are either odd (o) or even (e) as follows:
o, e, o, o, e,  o, o, e, o, o, e, ... because of the arithmetic
rule:
Odd + Odd = Even
Even + Even = Even
Odd + Even = Odd

2) By do two rounds of fibonacci, we can get from one "e" to the
next "e".  We don't need to bother checking its even.

3) To avoid re-computing past results, we ask for the past 
running total to be supplied, and the past pair of fibonacci 
numbers before doing our two rounds of fibonacci

4) We assume the passed in pair of fibonacci numbers don't exceed
are supplied limit, and on the next even fibonacci we can just test
for exceeding the limit there only.

5) Fibonacci numbers grow very fast (nearly doubling each time).  Since
the next even is found after two iterations, it means we have exponential
growth for the next fibonacci number.  For limit L, we'll find the sum
after O(log(L)) time.

@param  runningTotal    Total of even fibonacci numbers seen so far
@param  upperLimit      Limit number not to exceed the next even fibonacci
@param  n0              First of an adjacent pair of fibonacci numbers with
                        n0 < upperLimit
@param  n1              Next fibonacci number after n1 with n1 < upperLimit

@returns (updatedTotal,n3,n4) where updatedTotal is the supplied runningTotal
         plus the next even fibonacci number not exceeding the supplied
         upperLimit, n3 and n4 are the next pair of fibonacci numbers to be
         supplied for the next call to this method
*/
func sumNextEvenFibonacci(runningTotal:Int, upperLimit:Int, n0:Int, n1:Int) -> (Int, Int, Int)
{
    let n2 = n0 + n1
    let n3 = n2 + n1
    let n4 = n3 + n2

    if (n4 < upperLimit)
    {
        return (runningTotal + n4, n3, n4)
    }
    else
    {
        return (runningTotal, n3, n4)
    }
}

func eulerProblem_02()
{
    println("Problem 2\n\nEach new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:\n 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... \n\nBy considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.\n")
    var n0 = 1, n1 = 2, n2 = 0, runningTotal = 2
    do
    {
        (runningTotal, n0, n1) = sumNextEvenFibonacci(runningTotal, 4_000_000, n0, n1)
    } while (n1 < 4_000_000)
    println("The answer is \(runningTotal).\n")
}

eulerProblem_02()

程序输出:

Problem 2

Each new term in the Fibonacci sequence is generated by adding the previous two terms.      By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... 

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

The answer is 4613732.

答案 11 :(得分:0)

使用Kotlin的解决方案,我正在使用这些问题来练习我的数学并为我学习这门新语言:

import java.math.BigInteger

/**
 *
 * https://projecteuler.net/problem=2
 *
 * Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
 *
 * 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
 * By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
 *
 */
class Problem2 {

    var maxValue: Int = 4000000

    // Looking for this fibonacci value
    var fibonacci = 32
    var fibonacciValues = hashMapOf<Int, BigInteger>(0 to BigInteger.ONE, 1 to BigInteger.ONE);

    fun solution(): BigInteger {
        var solution: BigInteger = BigInteger.ZERO
        calculateFibonacci(fibonacci)

        fibonacciValues.filter {
            it.value < BigInteger.valueOf(maxValue.toLong()) &&
                    it.value.mod(BigInteger.ONE.add(BigInteger.ONE)).equals(BigInteger.ZERO)
        }.forEach {
            //println("Key: ${it.key} and ${it.value} and mv $maxValue")
            solution = solution.add(it.value)
        }

        return solution
    }

    private fun calculateFibonacci(n: Int): BigInteger? {
        if ( fibonacciValues.contains(n)) {
            return fibonacciValues.get(n)
        } else {
            val f = calculateFibonacci(n - 2)!!.add(calculateFibonacci(n - 1))

            fibonacciValues.put(n, f)
            return f
        }
    }

}

它有点冗长,因为我添加了可测试性,如果你想看单元测试,这里是:

https://github.com/moxi/project-euler-solutions/blob/master/code/src/test/kotlin/org/rcgonzalezf/onetoten/Problem2Test.kt

答案 12 :(得分:0)

每个第3个数字都是偶数,因此偶数之和是(n个纤维数的总和)/ 2。

但是,有些人。数字=(n + 2)&#39; s term - 2nd term(1)。

你可以从benet的公式获得第(n + 2)个词

答案 13 :(得分:0)

在javascript中你可以这样解决:

function add(a, b) {
    // body...
    return a + b;
}
function fabonacci(limit) {
    var i = 2; //parseInt(limit);
    var fabonacci = [0, 1];
    var evenFab = [];
    var valToPush = 0;
    var result = [];
    while (valToPush < 4000000) {
        valToPush = fabonacci[fabonacci.length - 2] + fabonacci[fabonacci.length - 1]
        i++;
        if ((valToPush % 2) == 0) {
            evenFab.push(valToPush);
        }
        if (valToPush > 4000000 || i > limit) {
            break;
        }
        fabonacci.push(valToPush);
    }
    result['sequence'] = fabonacci;
    result['sumOfEven'] = evenFab;
    return result;
}
var result = fabonacci(10);
console.log("Fabonacci sequence:" + result['sequence']);
console.log("Sum of Even Number:" + (result['sumOfEven']).reduce(add, 0));`

答案 14 :(得分:0)

a = 0
b = 1
c =0
sum = 0
d = 0

for s in range(4000000):    
    while(d<4000000):    
        d = a+b    
        if d%2 == 0:
        sum += d   
        print(d)    
        a = b    
        b = d


print    
print 
print("the sum is:"+str(sum))