鱼C论坛

 找回密码
 立即注册
查看: 3360|回复: 5

题目187:半质数

[复制链接]
发表于 2016-10-5 15:50:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Semiprimes

A composite is a number containing at least two prime factors. For example, 15 = 3 × 5; 9 = 3 × 3; 12 = 2 × 2 × 3.

There are ten composites below thirty containing precisely two, not necessarily distinct, prime factors: 4, 6, 9, 10, 14, 15, 21, 22, 25, 26.

How many composite integers, n < 108, have precisely two, not necessarily distinct, prime factors?


题目:

一个合数是至少两个质数因子的乘积,比如 15 = 3 × 5; 9 = 3 × 3; 12 = 2 × 2 × 3。

30 以内的数中有 10 个合数,它们有且仅有两个质数因子,这两个因子可能相同:4, 6, 9, 10, 14, 15, 21, 22, 25, 26。

请问,对于 n < 108,有多少个数字只有两个质数因子?这两个质数因子可能相同。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-9-22 11:25:03 | 显示全部楼层
  1. import numpy as np
  2. from numba import jit
  3. @jit
  4. def solve(n):
  5.         sieve=np.ones(n+1,dtype=bool)
  6.         for i in range(2, int((n+1)**0.5+1)):
  7.                 if sieve[i]:
  8.                         sieve[i*i::i]=False
  9.         plist = np.nonzero(sieve)[0][2:]
  10.         count = 0
  11.         for i in range(len(plist)):
  12.                 j = i
  13.                 while plist[i]*plist[j] < n:
  14.                         count += 1
  15.                         j += 1
  16.         return count
  17. print(solve(10**8))
复制代码

17427258
[Finished in 4.5s]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-21 18:43:43 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2021-2-20 20:38 编辑

C++ 322ms
  1. #include<iostream>
  2. #include<vector>
  3. #include<cstring>
  4. using namespace std;



  5. template<size_t size, typename T>
  6. void euler_sieve(bool (&is_prime)[size], vector<T>& primes) {
  7.     T i, k;
  8.     memset(is_prime, -1, size);
  9.     is_prime[0] = is_prime[1] = 0;

  10.     for (T i = 2; i < size; i++) {
  11.         if (is_prime[i]) {
  12.             primes.push_back(i);
  13.         }

  14.         for (T j : primes) {
  15.             k = i * j;

  16.             if (k >= size) {
  17.                 break;
  18.             }

  19.             is_prime[k] = false;

  20.             if (!(i % j)) {
  21.                 break;
  22.             }
  23.         }
  24.     }
  25. }



  26. int main() {
  27.     ios::sync_with_stdio(false);
  28.    
  29.     constexpr unsigned int UPPER_BOUND = 100000000;
  30.     static bool is_prime[UPPER_BOUND / 2];
  31.     vector<unsigned int> primes;
  32.     unsigned int i, j, result = 0;

  33.     euler_sieve(is_prime, primes);


  34.     for (i = 0; primes[i] * primes[i] < UPPER_BOUND; result += ++i);

  35.     for (j = i; i < primes.size(); i++) {
  36.         while (primes[i] * primes[j] >= UPPER_BOUND) {
  37.             j--;
  38.         }

  39.         result += j;
  40.         result++;
  41.     }


  42.     cout << result << endl;
  43.     return 0;
  44. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 14:49:37 | 显示全部楼层
优化来了。
  1. /*
  2. 答案:17427258
  3. 耗时:1.41251
  4.       0.643071 (8核)
  5. */
  6. #include <iostream>
  7. #include <vector>
  8. #include <cmath>
  9. #include <omp.h>
  10. using namespace std;

  11. const int N = 100000000;
  12. const int M = int(sqrt(double(N)));

  13. char cp[N];//cp[i]==1表示i为素数
  14. bool pm[N];//pm[i]==true表示i为两个素数的乘积

  15. int main(void)
  16. {
  17.   double t = omp_get_wtime();
  18.   memset(cp, 1, sizeof(cp));
  19.   int nCount = 0;
  20.   bool bContinue = true;
  21. #pragma omp parallel firstprivate(bContinue) shared(cp,pm) reduction(+:nCount)
  22.   {
  23.     for (int i = 2; i <= M; ++i)
  24.     {
  25. #pragma omp single copyprivate(bContinue)
  26.       {
  27.         bContinue = true;
  28.         if (cp[i] == 0)
  29.           bContinue = false;
  30.       }
  31.       if (!bContinue)
  32.         continue;
  33. #pragma omp for
  34.       for (int j = i * i; j < N; j += i)
  35.         cp[j] = 0;
  36.     }
  37. #pragma omp barrier
  38. #pragma omp for schedule(dynamic)
  39.     for (int i = 2; i <= M; ++i)
  40.     {
  41.       if (cp[i] == 0)
  42.         continue;
  43.       for (int j = i; i*j < N; ++j)
  44.       {
  45.         if (cp[j] == 1)
  46.           pm[i*j] = true;
  47.       }
  48.     }
  49. #pragma omp for
  50.     for (int i = 4; i < N; ++i)
  51.     {
  52.       if (pm[i])
  53.         ++nCount;
  54.     }
  55.   }
  56.   t = omp_get_wtime() - t;
  57.   cout << nCount << endl << t << endl;
  58.   return 0;
  59. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 20:07:44 | 显示全部楼层
本帖最后由 代号-K 于 2020-5-17 20:10 编辑

这题本质还是素数的求解,只是在求解的过程中加入了一些判断。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-17 20:11:02 | 显示全部楼层
本帖最后由 代号-K 于 2020-5-17 20:13 编辑


有个优化过的帖子,不知道在哪里了,这个帖子不是优化的,重新写一个吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-20 01:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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