204. Count Primes(python+cpp)

本文介绍了一种使用动态规划优化的素数计数算法,通过避免不必要的除法操作,显著提高了计算效率。以Python和C++代码实现,展示了如何快速找出小于给定正整数的所有素数数量。

题目:

Count the number of prime numbers less than a non-negative number, n.
Example:

Input: 10 
Output: 4 
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.

解释:
还是用动态规划的方式做,比写函数开根号的节省时间。
python代码:

from math import sqrt
class Solution(object):
    def countPrimes(self, n):
        """
        :type n: int
        :rtype: int
        """
        
        if n<=2:
            return 0
        isPrime=[True]*n
        isPrime[0]=isPrime[1]=False
        # 在选择除数时候的一个小技巧.大于一半的数是不可能做除数的.可以节省时间
        for i in xrange(2,int(n**0.5)+1):
            if isPrime[i]==True:
                '''
                j=i*i
                while j<n:
                    isPrime[j]=False
                    j+=i
                '''
                isPrime[i * i: n: i] = [False] * len(isPrime[i * i: n: i])  # 非常简洁的语句
        return sum(isPrime)

c++代码:

#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
    int countPrimes(int n) {
        vector<bool> isPrime(n,true);
        isPrime[0]=false;
        isPrime[1]=false;
        for (int i=2;i<int(sqrt(n))+1;i++)
        {
            if(isPrime[i])
            {
                int j=i*i;
                while (j<n)
                {
                    isPrime[j]=false;
                    j+=i;
           
                }
            } 
        }
        return count(isPrime.begin(),isPrime.end(),true);   
    }
};

总结:
也是再做的时候才发现j需要遍历到i**2+1就好了,这样写,时间变了原来的1/3,震惊。
python可以直接sum()一个bool数组来求数组中的True的个数,用python的切片实现赋值简直震惊,注意数组初始化为True
注意题目是less than n,所以数组元素初始化为n

1. GNU GCC 是常用的 C/C++语言编译器。现需要使用 g++将 luogu.cpp 编译为可执行文件 luogu,可以使用编译命令( )。 A. g++ -S luogu luogu.cpp B. g++ -S luogu.cpp luogu C. g++ -o luogu luogu.cpp D. g++ -o luogu.cpp luogu 2. 关于编译语言与解释语言,以下说法错误的是( )。 A. C++语言是编译语言,需要先经过编译得到可执行程序,才能交由机器执行。 B. 编译语言程序每一次执行都需要重新编译。 C. 解释器负责将解释语言的源程序翻译为可以执行的机器代码。 D. Python 是常见的解释语言。 3. 阅读下面的代码,若输入的 x 是 1 至 10 范围内的正整数,输出不可能是( )。 01 02 03 04 05 06 07 08 #include <iostream> using namespace std; int main() { int x; cin >> x; switch(x) { case 1: { cout << "A"; break; } case 3: { cout << "C"; } default: { cout << "Q"; } LUOGU SCP-J 2025 第一轮 C++语言试题 第 2 页,共 10 页 09 10 11 12 case 5: { cout << "E"; } } return 0; } A. A B. CQE C. QE D. Q 4. k(k>4)进制数 4321 与十进制数( )相等。 A. 4321 B. 4k4+3k3+2k2+k C. 4k3+3k2+2k+1 D. 10k 5. 阅读以下代码片段。当代码片段执行完毕后,ans 的值为( )。 01 02 03 04 05 06 int N = 10, ans = 0, x = 0; for(int i = 1; i <= N; i++) { for(int j = i + 1; j <= N; j++) { ans += ++x; } } A. 45 B. 55 C. 990 D. 1035 6. 给定一个空栈,支持入栈和出栈操作。将 1 至 10 依次入栈,第一个出栈的数为 8,则第 二个出栈的数不可能为( )。 A. 1 B. 7 C. 9 D. 10 7. 有序表中有 100 个元素,使用二分法查找元素 X。有( )个数可以通过恰好 5 次查找找 到。 A. 100 B. 32 C. 31 D. 16 8. 下面的表格是无向图 G 的邻接矩阵,图 G 中度最大的点的度为( )。 A B C D E A 0 1 1 0 1 B 1 0 1 0 0 C 1 1 0 1 1 D 0 0 1 0 1 E 1 0 1 1 0 LUOGU SCP-J 2025 第一轮 C++语言试题 第 3 页,共 10 页 A. 1 B. 2 C. 3 D. 4 9. 8 支队伍均分为第一组与第二组进行小组赛。A 队和 B 队在同一组,而与 C 队不在同一组 的分组方案数有( )种。 A. 10 B. 20 C. 30 D. 40 10. 将一根长度为 3 的木棍折为三段,当断点的位置在木棍中等概率分布时,三段木棍可以 构成三角形的概率为( )。 A. 1 B. 0.5 C. 0.25 D. 0.125 11. 下列关于快速排序的说法中,不正确的是( )。 A. 快速排序典型地应用了分治法的思想。 B. 快速排序的最坏时间复杂度为 O(n log n)。 C. 快速排序是基于交换的排序。 D. sort 函数是 STL 提供的快排函数,同时结合了堆排序、插入排序等技术。 12. 关于整数的各种 8 位二进制编码方法,说法错误的是( )。 A. -17 的原码为 10010001 B. 22 的补码为 00010110 C. -13 的反码为 11110010 D. 以上说法存在错误 13. 表达式(x-2x-1/2) 4 中,x 的系数为( )。 A. 12 B. -12 C. 24 D. -24 14. 二叉树 T 的中序遍历为 CGEADBF,后序遍历为 GECDFBA,则其前序遍历为( )。 A. ACEGBDF B. ACGEBDF C. ABDFCEG D. ABCDEFG 15. 2024 年,来自谷歌 DeepMind 的米斯·哈萨比斯和约翰·江珀获得了( ),以表彰他们 在人工智能方面的贡献。 A. 王选奖 B. 图灵奖 C. 诺贝尔奖 D. 贝尔奖 LUOGU SCP-J 2025 第一轮 C++语言试题 第 4 页,共 10 页 二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 T,错误填 F;除特 殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分) (1) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 #include <bits/stdc++.h> using namespace std; int main() { int l, r; cin >> l >> r; int cnt = 0; long long sum = 0; for(int i = l; i <= r; ++i) { if((i & (i - 1)) != 0) { cnt += 1; sum += i; } } cout << cnt << " " << sum << endl; return 0; } 假设输入的 l 和 r 均为不超过 106的正整数,且满足 l<=r,完成下面的判断题和单选题。 ·判断题 16. 当输入为 2 5 时,程序的输出为 2 8。( ) 17. 程序的输出总是两个正整数。( ) 18. 将第 8 行的 long long 改为 int,程序行为不变。( ) ·单选题 19. 当输入为 1 100 时,程序的输出为( )。 A. 93 4923 B. 92 4823 C. 93 4823 D. 92 4923 20. 当输入为 10000 1000000 时,程序的第一个输出为( )。 A. 989993 B. 989994 C. 989995 D. 989996 LUOGU SCP-J 2025 第一轮 C++语言试题 第 5 页,共 10 页 (2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <bits/stdc++.h> using namespace std; int main() { int n, m; cin >> n >> m; vector<int> a(n); for(int i = 0; i < n; ++i) { cin >> a[i]; } vector<int> dp(m + 1); dp[0] = 0; for(int i = 1; i <= m; ++i) { int now = 0; for(int j = 0; j < n; ++j) { if(i >= a[j] && dp[i - a[j]] == 0) { now = a[j]; } } dp[i] = now; } cout << dp[m] << endl; return 0; } 假设输入的 n 和 m 均为不超过 1000 的正整数,输入的 a[i]均为不超过 m 的正整数,完成下 面的判断题和单选题。 判断题 21. 当输入为 3 5 1 3 4 时,程序的输出为 0。( ) 22. (2 分)当输入的数组 a 为{1}且 m 为偶数时,程序的输出为 0。( ) 23. 将第 16 行的条件 i >= a[j] && dp[i - a[j]] == 0 改为 dp[i - a[j]] == 0,程 序可能会产生编译错误。( ) LUOGU SCP-J 2025 第一轮 C++语言试题 第 6 页,共 10 页 ·单选题 24. 当输入为 4 13 1 2 3 4 时,程序的输出为( )。 A. 0 B. 1 C. 2 D. 3 25. 当输入为 7 1000 1 2 3 4 5 6 7 时,程序的输出为( )。 A. 0 B. 1 C. 2 D. 3 26. (4 分)当输入的数组 a 为{1,2,3,4,5}时,有( )个符合数据范围的整数 m 使得输 出为 3。 A. 165 B. 166 C. 167 D. 168 (3) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include<bits/stdc++.h> using namespace std; vector <int> primes; int comp_by[2000005]; void sieve(int n) { for(int x = 2; x <= n; x++) { if(comp_by[x] == 0) primes.push_back(x); for(int i = 0; i < primes.size(); i++) { if(x * primes[i] > n) break; comp_by[x * primes[i]] = primes[i]; if(x % primes[i] == 0) break; } } } int main() { freopen("input.txt", "w", stdout); freopen("output.txt", "r", stdin); int n; cin >> n; sieve(n); for(int i = 1; i <= n; i++) cout << comp_by[i] << ' '; return 0; } LUOGU SCP-J 2025 第一轮 C++语言试题 第 7 页,共 10 页 假设输入的 n 是不超过 106的正整数,完成下面的判断题和选择题。 提示:伯特兰-切比雪夫定理:对任意 n>1,存在质数 p 使得 n<p<2n。 ·判断题 27. 程序将从 input.txt 读入数据,输出到 output.txt。( ) 28. 交换程序的第 12 行和第 13 行,不会导致数组越界。( ) 29. 对于所有正整数 i,满足 1<=i<=n,输出的第 i 个数是 0 当且仅当 i 是质数。( ) ·单选题 30. 该程序的的主要流程最接近( )。 A. 递归法 B. 动态规划 C. 埃拉托斯特尼筛 D. 欧拉筛 31. 将程序的第 14 行移动到第 11 行,当输入为 1000000 时,输出的第( )个数会发生 改变。 A. 75 B. 45 C. 97 D. 105 32. (4 分)当输入为 100 时,输出的所有数字之和为( )。 A. 154 B. 194 C. 197 D. 214 三、完善程序(单选题,每小题 3 分,共计 30 分) (1)(全排列检查)给定长度为 n 的数组 a,判断其是否构成全排列。如果 1,2,...,n 都恰 好在数组 a 中出现且仅出现一次,那么就称这个数组是一个全排列。 试补全程序。 01 02 03 04 05 06 07 08 09 10 11 12 #include<bits/stdc++.h> using namespace std; bool is_permutation(vector<int> &a) { int n = ① ; vector<int> count(); for(int i = 0; i < n; i++) { if() count[a[i]]++; else ④ ; } LUOGU SCP-J 2025 第一轮 C++语言试题 第 8 页,共 10 页 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 for(int i = 1; i <= n; i++) if(count[ ⑤ ] > 1) return false; return true; } int main() { int n; cin >> n; vector<int> a(n); for(int i = 0; i < n; i++) cin >> a[i]; if(is_permutation(a)) cout << "The sequence is a permutation."; else cout << "The sequence is not a permutation."; return 0; } 33. ①处应填( )。 A. a.length() B. a.size() C. a.back() D. a.capacity() 34. ②处应填( )。 A. 0 B. n C. n + 1 D. 1000000000 35. ③处应填( )。 A. 1 <= a[i] && a[i] <= n B. 1 <= a[i] <= n C. 1 <= a[i] || a[i] <= n D. a[i] < 1 || a[i] > n 36. ④处应填( )。 A. break B. continue C. return true D. return false 37. ⑤处应填( )。 A. i B. a[i] C. i – 1 D. i / 2 (2)(跳跃)给定一个数组 a[0],a[1],...,a[n-1],每次跳跃从从当前位置 x 跳至位置 a[x]。回答 q 次询问,每次给出(x,k),输出从 x 跳跃 k 次后的位置编号。 试补全程序。 LUOGU SCP-J 2025 第一轮 C++语言试题 第 9 页,共 10 页 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> using namespace std; const int N = 100010, LOG = 20; int a[N], dp[N][LOG]; int main() { int n, q; cin >> n >> q; for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n; i++) { dp[i][0] = ① ; } for (int k = 1; k < LOG; k++) { for (int i = 0; i < n; i++) { dp[i][k] = ② ; } } while (q--) { int x, k; cin >> x >> k; int u = x; for (int j = 0; j < LOG; j++) { if () { u = ④ ; } } cout << ⑤ << endl; } return 0; } 38. ①处应填( )。 A. i B. a[i] C. 0 D. dp[i][1] LUOGU SCP-J 2025 第一轮 C++语言试题 第 10 页,共 10 页 39. ②处应填( )。 A. dp[dp[i][k - 1]][k - 1] B. dp[i][k - 1] + dp[i][k - 1] C. dp[i - 1][k - 1] D. dp[k - 1][i] 40. ③处应填( )。 A. k & j B. k >> j C. (k >> j) & 1 D. (k >> j) ^ 1 41. ④处应填( )。 A. dp[j][u] B. dp[k][u] C. dp[u][j] D. a[u] 42. ⑤处应填( )。 A. u B. x C. k D. dp[u][0]
最新发布
08-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值