欧拉计划(1~3)ps:以后看题一定要认真

那天的题挺简单的

下面来看下

  No1

  If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

  Find the sum of all the multiples of 3 or 5 below 1000.

//project euler num1

#include <stdio.h>

#include <stdlib.h>

#include <string.h>



int main()

{                                                      

    int sum = 0;

    int i;

    for(i = 0; i < 1000; i++)

    {   

        if(i % 3 == 0 || i % 5 == 0)

            sum += i;

    }   



    printf("The sum is %d\n", sum);

}

  第一题很简单,不解释~

  No 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

  第二题是求斐波那契数列小于 4e6 的那些偶数项的和,很简单的想到了递归算法

  

//project euler pro02

#include <iostream>

#include <string>

#include <vector>

using namespace std;



int fib_temp[10000];//避免重复运算,算好的项存入数组



int fib(int n)

{

    if(n == 1)                                                                                       

    {

        fib_temp[0] = 1;

        return fib_temp[0];

    }

    else if( n == 0)

    {

        fib_temp[1] = 2;

        return fib_temp[1];

    }

    else

    {

        if(fib_temp[n - 1] != 0)

        {                                                                                         

            if(fib_temp[n - 2] != 0)

                 return fib_temp[n - 1] + fib_temp[n - 2];//如果已经预存,直接返回

            else

                fib_temp[n - 2] = fib( n - 2);

                return fib_temp[n - 1] + fib_temp[n - 2];

        }

        else

        {

            fib_temp[n - 1] = fib(n - 1);

            fib_temp[n - 2] = fib(n - 2);

            return fib_temp[n - 1] + fib_temp[n - 2];

        }

    }

}



int sum_even_fib(int top_num)

{



    int i = 0;

    int sum = 0;

    int temp = 0;

    while(1)

    {

        if(i % 2 == 0)

        {

            if((temp = fib(i)) < top_num)

                sum += temp;

            else

                break;

        }

        i++;

    }

    return sum;

}



int main()

{



    int sum = sum_even_fib(400000000);

    cout << sum << endl;

    return 0;

}             

                

  就是这样,没有选用最基本的递归方法是因为效率过低,不如把算好的想先存入数组,避免重复计算。

  但是这让我想起了之前的动态规划算法:

  递归算法是很简单的自顶向下,从上可以看出是从n一步步的计算到第一项;

  但是动态规划恰恰相反,它是先从第一项开始计算,然后把算好的结果存入数组以备后用。

  //project euler pro02                                                                                            

   #include <iostream>

   #include <string>

   #include <vector>

   using namespace std;

   

   int fib_temp[10000];

   //設立預存數組

   int fib(int n)

  {

      if( n == 0 || n == 1)

      {

          if(fib_temp[0] == 0)

              fib_temp[0] = 1;

          if(fib_temp[1] == 0)

              fib_temp[1] = 2;

          //對前兩項初始化

      }

      else

      {

          for(int i = 2; i <= n; i++)

          {

              if(fib_temp[i] == 0)

                  fib_temp[i] = fib_temp[i - 1] + fib_temp[i - 2];

              //用循環計算後面的項

          }

      }

      return fib_temp[n];

      //直接返回數組中的項

  }

  

 int sum_even_fib(int top_num)

 {

      int i = 0;

      int sum = 0;

      int temp = 0;

      while(1)

      {

          if((temp = fib(i)) % 2 == 0)

          {

              if(temp < top_num)

                  sum += temp;

              else

                  break;

          }

          cout << fib(i) << endl;

          i++;

      }

      return sum;     

 }

  int main()

  {

      int sum = sum_even_fib(4e6);

      cout << sum << endl;

      return 0;

  }                                                  

          

  No3

  The prime factors of 13195 are 5, 7, 13 and 29.

  What is the largest prime factor of the number 600851475143 ?

  我会说就是这个我没有看清楚题么,我看做是求小于这个数的所有素数~

  但是题目是求小于这个数的最大素因子。

  悲伤~~

  好吧,两个都做完了,先看计算最大素因子。

   #include <iostream>                                                                              

   #include <string>

   #include <vector>

   #include <math.h>

   

   using namespace std;

   

   

   bool is_prime(long long int i)

  {

      long long int j;                                                                           

      for(j = 2; j <= sqrt(i); j ++)

      {    

          if(i % j == 0)

              return false;

      }

      if(j > sqrt(i))

          return true;

  }

  //这是判断素数的

  

  void max_prime_facter(long long int n)

  {

      if(is_prime(n))

      {

          cout << n << endl;

          return;

          //如果n本身就是素数,直接输出

      }

      for(long long int i = 2; i < (n / 2); ++i)

      {

          if(n % i == 0)

          {

              n = n / i;

              //如果找到一个小的因子,替换n为n/i

              cout << "factor is " << i << endl;

              i = 2;

              //重置循环变量

              if(is_prime(n))

              {   

                  cout << n << endl;

                  //如果在过程中发现n变为了素数,说明

    得到了最大的素因子

                  break;

              }

          }

      }

  }

  

  int main(int argc, const char *argv[])

  {

      long long int n = 600851475143;

      max_prime_facter(n);

      return 0;

  }                                      

                           

  看~不难吧。

  那么问题就来了, 挖掘机到底那家强!!

  小扯一下,那么如果我想输出小于这个数的所有素数呢?

  先说一下这个程序的基本思想:

  传统的输出小于这个数的所有素数就是, 

  一个循环,依次判断,但是判断素数是一个很繁琐的事情。

  所以我们就想可不可以把一些数省掉呢?

  首先所有偶数都是合数。

  那么自然而然的就想到了算数基本定理:所有合数都可以表示为素因子的乘积。

   #include <iostream>

   #include <string>

   #include <vector>                                  

   #include <stdio.h>

   #include <stdlib.h>

   #include <string.h>

   #include <math.h>

   using namespace std;

   

  bool is_prime(long long int i)

  {

      for(long long int j = 2; j <= sqrt(i); j ++)

      {

          if(i % j == 0)

              return false;

      }

      if(i > sqrt(i))

          return true;

  }

  //判断素数的函数

  vector<int> vec_prime;

  //一个存放素数的数组

  void  prime_number(long long int n)

  {

      long long int max;

      for (int i = 2; i < n; i++) 

      {

          if(vec_prime.size() != 0)

          //一开始数组内是没有元素的

          {

              vector<int>::iterator it ;

              for( it = vec_prime.begin(); it != vec_    prime.end(); ++it)

              {

                  if(i % (*it) == 0) 

                     break;

                  //依次判断数组内有没有其的因子

              }

             if(it != vec_prime.end()) 

                 continue;       

             //这表示有他的素因子

          }

          if(is_prime(i) == true)

          //到这里说明数组中没有这个数的因子

          //因为我们知道一切正整数都可以表示成素数的乘积

          //反之,如果这个数不能表示成素数的乘积

          //那么这个数本身很可能就是素数

          //所以判断他是否是素数,是的话就加入数组

          {

              vec_prime.push_back(i);

              cout << i << endl;

              //依次输出素数

          }

      } 

      return ;

  }

  

  int main()           

  {

  

      long long int n = 600851475143;

      prime_number(n);

      return 0;

  }                                                         

  可以看到这个算法其实是非常快速的~

 

  补充:

    今早起来突然想到上面的程序是不是还不够快呢~

    可不可以把判断素数的函数省掉呢?

    事实上,判断素数就是多余的。

    因为所有正整数都可以表示为它一组素因子的乘积或者是它本身与 1 的乘积。

 1 #include <iostream>                                

  2 #include <string>

  3 #include <vector>

  4 #include <stdio.h>

  5 #include <stdlib.h>

  6 #include <string.h>

  7 #include <math.h>

  8 using namespace std;

  9 

 10 bool is_prime(long long int i)

 11 {

 12     for(long long int j = 2; j <= sqrt(i); j ++)

 13     {

 14         if(i % j == 0)

 15             return false;

 16     }

 17     if(i > sqrt(i))

 18         return true;

 19 }

 20 //判断素数的函数

 21 vector<int> vec_prime;

 22 //存入第一个素数

 23 //一个存放素数的数组

 24 void  prime_number(long long int n)

 25 {

 26 

 27     if(vec_prime.size() == 0)

 28         vec_prime.push_back(2);

 29 

 30     long long int max;

 31     for (int i = 3; i < n; i += 2)

 32     {

 33         //一开始数组内是没有元素的

 34             vector<int>::iterator it ;

 35             for( it = vec_prime.begin(); it != vec_prime.end(); ++it)

 36             {

 37                 if(i % (*it) == 0) 

 38                    break;

 39                 //依次判断数组内有没有其的因子

 40             }

 41            if(it != vec_prime.end())      

 42                continue;

 43            else if(it == vec_prime.end())

 44            {

 45                 vec_prime.push_back(i);

 46                 cout << i << endl;

 47            }

 48            //这表示有他的素因子

 49         //到这里说明数组中没有这个数的因子

 50         //因为我们知道一切正整数都可以表示成素数的乘积

 51         //反之,如果这个数不能表示成素数的乘积

 52         //那么这个数本身很可能就是素数

 53         //所以判断他是否是素数,是的话就加入数组

 54             //依次输出素数

 55     } 

 56     return ;

 57 }

 58 

 59 int main()

 60 {

 61 

 62     long long int n = 600851475143;

 63     prime_number(n);

 64     return 0;

 65 }                       

    实验一下发现这个程序还是非常快速的。

    那么我们就得到了这样的程序:

  

 

  最后再说一下:

  今天学习了c++中的两个新的数据类型long long int 和 _int64.

  参考文章:

  http://www.cnblogs.com/jiai/articles/2613900.html

  http://www.cnblogs.com/felove2013/articles/3880590.html

你可能感兴趣的:(欧拉计划)