zoukankan      html  css  js  c++  java
  • 欧拉计划(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

  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/xujie-nm/p/4021066.html
Copyright © 2011-2022 走看看