鱼C论坛

 找回密码
 立即注册
楼主: 欧拉计划

题目10:计算两百万以下所有质数的和

[复制链接]
发表于 2021-3-7 23:44:34 From FishC Mobile | 显示全部楼层
a1351468657 发表于 2021-3-6 18:35
time=1
两百万以内素数和为:143042032122


可以试下欧拉筛法, 参考一下49#
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-8 16:50:46 | 显示全部楼层
永恒的蓝色梦想 发表于 2021-3-7 23:44
可以试下欧拉筛法, 参考一下49#

好的,谢谢大佬!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-7 22:00:35 | 显示全部楼层
  1. result=[]
  2. for num in range(2,2000001):
  3.     for each in range(2,int(num**0.5)+1):
  4.         if num % each==0:
  5.             break
  6.     else:
  7.         result.append(num)

  8. print(sum(result))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-10 22:40:02 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>

  3. static int count;

  4. int is_prime(int value)
  5. {
  6.         int j;
  7.         if (value == 2) return 1;
  8.         for(j=2; j<sqrt(value)+1; j++){
  9.                 count += 1;
  10.                 if (j>3) j++;
  11.                 if (value%j==0) return 0;
  12.         }
  13.         return 1;
  14. }

  15. int main(void)
  16. {
  17.         long long int sum = 0;
  18.         int i;
  19.        
  20.         for(i = 2; i<=2000000; i++)
  21.         {
  22.                 if (is_prime(i)) sum+=i;
  23.         }
  24.        
  25.         printf("sum = %lld\n", sum);
  26.         printf("count = %d\n", count);
  27.        
  28.         return 0;
  29. }
  30. //sum = 142913828922
  31. //count = 91357987
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-10 21:30:38 | 显示全部楼层
#计算2百万之内的素数之和
import math
#判断是否是素数
def is_prime(number):
    if number > 1:
        if number == 2:
            return True
        if number % 2 == 0:
            return False
        for a in range(3,int(math.sqrt(number) + 1),2):
            if number % a == 0:
                return False
        return True
    return False
   
#生成器(返回素数)
def get_prime(number):
    while True:
        if is_prime(number):
            yield number
        number += 1

#求和
def result():
    result = 2
    for next_prime in get_prime(3):
        if next_prime < 10:
            result += next_prime
        else:
            print(result)
            return  
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-29 09:53:45 | 显示全部楼层
  1. #include<stdio.h>

  2. #define MAX  2000000

  3. int main(void)
  4. {
  5.         unsigned int sum = 2;
  6.        
  7.         for(int i = 2;i < MAX;i++)
  8.         {
  9.                 for(int j = 2;j < (i / 2);j++)
  10.                 {
  11.                         if(i % j == 0)
  12.                         {
  13.                                 flag = 1;
  14.                                 break;
  15.                         }
  16.                         else
  17.                                 flag = 0;
  18.                 }
  19.                 if(flag == 0)               
  20.                         sum += i;       
  21.         }
  22.        
  23.         printf("%d",sum);
  24.        
  25.         return 0;
  26. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-13 18:21:30 | 显示全部楼层
0.8秒 答案142913828922
  1. #include <stdio.h>
  2. #include <math.h>

  3. void main(void)
  4. {
  5.         long long sum = 0;
  6.         long i,j,temp;
  7.        
  8.         for (i = 2;i < 2000000;i++)
  9.         {
  10.                 temp = sqrt(i);
  11.                 for (j = 2;j <= temp;j++)
  12.                 {
  13.                         if (i % j == 0)
  14.                                 break;
  15.                 }
  16.                 if (j > temp)
  17.                         sum += i;
  18.         }
  19.         printf("%lld\n",sum);
  20. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-2 18:25:54 | 显示全部楼层
本帖最后由 guosl 于 2022-1-2 18:33 编辑

本题最快的算法是应用筛法。如果应用朴素的穷举法,在主机(CPU)上运行的时间基本上都在0.1秒左右。但如果用GPU进行编程则我们可以得到眼前一亮的结果。
  1. /*
  2. 答案:142913828922
  3. 耗时:0.014134(GTX970)
  4. */
  5. #include "cuda_runtime.h"
  6. #include "device_launch_parameters.h"
  7. #include <stdio.h>

  8. const int D = 2000000;
  9. const int nBlockDim = 128;
  10. const int nBlocks = 128;

  11. __device__ bool isprime(int n)
  12. {
  13.   if ((n & 1) == 0)
  14.     return false;
  15.   int d = (int)sqrt((double)n);
  16.   for (int i = 3; i <= d; i += 2)
  17.   {
  18.     if ((n % i) == 0)
  19.       return false;
  20.   }
  21.   return true;
  22. }

  23. __global__ void findprime(int s, int* r)
  24. {
  25.   __shared__ int lm[nBlockDim];
  26.   lm[threadIdx.x] = 0;
  27.   int n = s + 2 * (threadIdx.x + blockIdx.x * nBlockDim);
  28.   if (n <= D)
  29.   {
  30.     if (isprime(n))
  31.       lm[threadIdx.x] = n;
  32.   }
  33.   __syncthreads();
  34.   int k = nBlockDim / 2;
  35.   while (k > 0)
  36.   {
  37.     if (threadIdx.x < k)
  38.       lm[threadIdx.x] += lm[threadIdx.x + k];
  39.     __syncthreads();
  40.     k /= 2;
  41.   }
  42.   if (threadIdx.x == 0)
  43.     r[blockIdx.x] = lm[0];
  44. }

  45. int main(void)
  46. {
  47.   int* pM = NULL;
  48.   int* p_dM = NULL;
  49.   int s = 3;
  50.   long long nSum = 2;
  51.   cudaError_t cudaStatus;
  52.   int nPId = 0;
  53.   cudaStatus = cudaSetDevice(nPId);//设置计算卡
  54.   if (cudaStatus != cudaSuccess)
  55.   {
  56.     fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
  57.     goto Error;
  58.   }
  59.   cudaDeviceProp deviceProp;
  60.   cudaGetDeviceProperties(&deviceProp, nPId);
  61.   printf("GPU Device %d: "%s" with compute capability %d.%d\n\n",
  62.     nPId, deviceProp.name, deviceProp.major, deviceProp.minor);
  63.   //在显卡上分配内存
  64.   cudaStatus = cudaSetDevice(0);
  65.   cudaStatus = cudaHostAlloc((void**)&pM, nBlocks * sizeof(int), cudaHostAllocDefault);
  66.   if (cudaStatus != cudaSuccess)
  67.   {
  68.     fprintf(stderr, "CUDA alloc memory failed!");
  69.     goto Error;
  70.   }
  71.   cudaStatus = cudaMalloc((void**)&p_dM, nBlocks * sizeof(int));
  72.   if (cudaStatus != cudaSuccess)
  73.   {
  74.     fprintf(stderr, "cudaMalloc failed!");
  75.     goto Error;
  76.   }
  77.   while (s <= D)
  78.   {
  79.     findprime << <nBlocks, nBlockDim >> > (s, p_dM);
  80.     cudaDeviceSynchronize();
  81.     cudaMemcpy(pM, p_dM, nBlocks * sizeof(int), cudaMemcpyDeviceToHost);
  82.     for (int i = 0; i < nBlocks; ++i)
  83.       nSum += pM[i];
  84.     s += 2 * nBlocks * nBlockDim;
  85.   }
  86.   printf("%lld\n", nSum);
  87. Error:
  88.   if (p_dM != NULL)
  89.   {
  90.     cudaFree(p_dM);
  91.     p_dM = NULL;
  92.   }
  93.   if (pM != NULL)
  94.   {
  95.     cudaFreeHost(pM);
  96.     pM = NULL;
  97.   }
  98.   return 0;
  99. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-28 21:19:06 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <vector>
  3. using std::vector;
  4. int main()
  5. {
  6.     vector<long long> prime;
  7.     vector<long long>::iterator it;
  8.     long long i,sum = 2;   
  9.     prime.push_back(2);
  10.     for(i=2;i<2e6;i++)
  11.     {
  12.         for(it=prime.begin();it!=prime.end();it++)
  13.         {
  14.             if(i%*it==0)
  15.                 goto loop;
  16.         }
  17.         prime.push_back(i);
  18.         sum += i;
  19.         loop:;
  20.     }         
  21.     printf("%lld",sum);
  22. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-22 18:10:47 | 显示全部楼层
209s蚌埠住了
  1. #include <stdio.h>
  2. #define NUM 2000000

  3. int main()
  4. {
  5.         int i,n=0,x=3;
  6.         unsigned long long int result=2,s=1;

  7.         while(x<NUM)
  8.         {
  9.                 for(i=2;i<x;i++)
  10.                 {
  11.                         if(x%i==0){
  12.                                 n++;
  13.                                 x++;
  14.                                 break;
  15.                         }
  16.                 }
  17.                
  18.                 if(n==0){
  19.                         result+=x;
  20.                         s++;
  21.                         x++;
  22.                         continue;
  23.                 }
  24.                
  25.                 n=0;
  26.         }
  27.         printf("%lld",result);
  28.         return 0;
  29.        
  30. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-18 20:19:06 | 显示全部楼层
运行结果:
142915828922
It costs 0.376059 s
  1. import time
  2. import math


  3. def euler_prime(num_range):
  4.     bool_prime = [True] * (num_range-1)
  5.     for i in range(2, int(math.sqrt(num_range))):
  6.         if bool_prime[i-2]:
  7.             for j in range(2, int(math.sqrt(i)) + 1):
  8.                 if i % j == 0:
  9.                     break
  10.         if bool_prime[i-2]:
  11.             for k in range(i*i, num_range, i):
  12.                 bool_prime[k - 2] = False
  13.     print(sum(i for i in range(2, num_range + 1) if bool_prime[i-2]))


  14. start = time.perf_counter()
  15. euler_prime(2000000)
  16. print('It costs %f s' % (time.perf_counter() - start))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-8 11:21:12 | 显示全部楼层
  1. use rayon::prelude::*;
  2. use std::time::Instant;

  3. const N: i64 = 2000000;

  4. fn main() {
  5.     let now = Instant::now();
  6.     let mut primes = Vec::new();
  7.     let mut cur = 10;
  8.     // bootstrap
  9.     for i in 2..cur {
  10.         if primes.iter().all(|p| i % p != 0) {
  11.             primes.push(i);
  12.         }
  13.     }
  14.     while cur < N {
  15.         let next = std::cmp::min(cur * cur, N);
  16.         let mut addition: Vec<_> = (cur..next)
  17.             .into_par_iter()
  18.             .filter(|x| {
  19.                 for p in primes.iter() {
  20.                     if x % p == 0 {
  21.                         return false;
  22.                     }
  23.                     if x / p < *p {
  24.                         break;
  25.                     }
  26.                 }
  27.                 true
  28.             })
  29.             .collect();
  30.         primes.append(&mut addition);
  31.         cur = next;
  32.     }
  33.     let num: i64 = primes.into_par_iter().sum();
  34.     println!("cost {} ms.", now.elapsed().as_millis());
  35.     println!("{}", num)
  36. }
复制代码

---
cost 22 ms.
142913828922
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-2 10:59:13 | 显示全部楼层
  1. import time
  2. start = time.time()


  3. def is_prime(n):
  4.     if n <= 1:
  5.         return False
  6.     for i in range(2, int(n ** 0.5) + 1):
  7.         if n % i == 0:
  8.             return False
  9.     return True


  10. total = 0
  11. for i in range(1, 2000000):
  12.     if is_prime(i):
  13.         total += i

  14. print(total)


  15. end = time.time()
  16. print(f'time:{end - start}')
复制代码

142913828922
time:13.038543701171875
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-19 20:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表