• 欧拉计划(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
    ", 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

  • 相关阅读:
    [BZOJ] IOI2015 Boxes纪念品盒
    [BZOJ] 聚会
    [BZOJ] 地精部落
    [BZOJ] 最长距离
    正则
    cookie实例 记住用户名密码
    cookie封装
    碎片整合 例子
    闭包 tab切换 实例
    闭包
  • 原文地址:https://www.cnblogs.com/xujie-nm/p/4021066.html
Copyright © 2020-2023  润新知