质数口袋
#include<iostream>
using namespace std;
bool prime(int n){
    for(int i = 2;i*i<=n;i++){
        if(n%i==0){
            return false;
        }
    }
    return true;
}
int main(){
    int num;
    
    while(cin>>num){
        int sum = 0;
        int count=0;
        int i = 2;
        while(sum<num){
            if(prime(i)){
                sum+=i;
                if(sum<=num){
                count++;
                cout<<i<<endl;
                }
            }
            i++;
        }
        cout<<count<<endl;
    }
    
    return 0;
}

一、先分析 原代码的 3 个核心问题(必须修复)

✅ 问题 1:质数判断函数prime(n)有逻辑缺陷 & 健壮性不足

  • 没有处理 n<=1 的情况(虽然主函数i从 2 开始,但函数本身应该具备健壮性);
  • 对偶数的判断完全冗余:比如判断9是不是质数,明明可以先判断偶数直接排除,原代码还是会循环i=2,3
  • i*i <=n 存在整型溢出风险:如果n很大(比如接近int最大值),i*i会溢出变成负数,导致判断失效。

✅ 问题 2:主函数累加逻辑 冗余且有瑕疵

原代码逻辑:sum += i 累加质数 → 判断sum<=num → 满足则计数。

问题:如果sum+i已经超过num,依然会执行sum += i,导致 sum 的值是错误的(超出 num),只是后续不计数而已,属于「无效累加」,还多了一层嵌套if判断,代码冗余。

✅ 问题 3:性能极低(最核心)

每一个数字i都单独调用prime(i)判断是否为质数,这是「暴力判断质数」的典型低效写法:

  • 比如判断100以内的质数,会对2,3,4,...,100逐个做质数判断,每个判断的时间复杂度是O(n​);
  • 整体时间复杂度达到 O(n根号n​),当num较大时(比如num=1e5),运行会明显卡顿。
#include<iostream>
#include<cmath>  // 用于sqrt函数
using namespace std;

// 优化后的质数判断函数:高效+健壮+无缺陷
bool prime(int n) {
    if (n <= 1) return false;    // 1及以下都不是质数
    if (n == 2) return true;     // 2是唯一的偶质数
    if (n % 2 == 0) return false;// 所有偶数直接排除,循环只需要判断奇数,效率翻倍
    // 从3开始,只遍历奇数,循环上限用sqrt(n),无溢出风险
    for (int i = 3; i <= sqrt(n); i += 2) {
        if (n % i == 0) return false;
    }
    return true;
}

int main(){
    int num;
    while(cin >> num){
        int sum = 0;
        int count = 0;
        int i = 2;
        while(true){
            if (prime(i) && (sum + i) <= num) { // 预判累加和,无无效累加,核心优化
                sum += i;
                count++;
                cout << i << endl;
            } else if (prime(i) && (sum + i) > num) {
                // 质数累加后超界,直接退出循环,无需继续遍历
                break;
            }
            i++;
            // 边界保护:当i超过num时,一定超界,退出
            if(i > num) break;
        }
        cout << "质数个数:" << count << endl;
    }
    return 0;
}

三、版本二:进阶优化版(埃拉托斯特尼筛法,性能暴增 100~1000 倍,强烈推荐)

✅ 核心优化思路:为什么这个版本性能碾压?

你的原代码和基础优化版,本质都是「逐个数字判断是否为质数」,属于暴力枚举

埃拉托斯特尼筛法(埃氏筛)预处理思想一次性筛选出 [2, num] 范围内的所有质数,时间复杂度仅为 O(nloglogn),这是质数相关问题的最优解法之一,也是竞赛 / 工程中必用的写法。

✅ 埃氏筛法 核心原理(一句话看懂)

先假设所有数都是质数,然后从最小的质数2开始,把2的所有倍数标记为「非质数」;再找下一个未被标记的数3,把3的所有倍数标记为非质数;以此类推,最终未被标记的数就是质数

✅ 适配你的业务逻辑

筛出 [2, num] 内的所有质数 → 从小到大累加这些质数 → 累加和不超过 num 就计数,超过就停止,完美匹配需求。

#include<iostream>
#include<vector>
using namespace std;

int main(){
    int num;
    while(cin >> num){
        if(num < 2){ // 边界判断:小于2的数没有质数
            cout << 0 << endl;
            continue;
        }
        // ========== 埃氏筛:一次性筛选出[2,num]的所有质数 ==========
        vector<bool> is_prime(num + 1, true); // is_prime[x]表示x是否是质数
        is_prime[0] = is_prime[1] = false;    // 0和1不是质数
        for(int i = 2; i*i <= num; ++i){
            if(is_prime[i]){ // 如果i是质数,标记i的所有倍数为非质数
                for(int j = i*i; j <= num; j += i){
                    is_prime[j] = false;
                }
            }
        }

        // ========== 你的核心业务逻辑:累加质数+统计个数 ==========
        int sum = 0;
        int count = 0;
        for(int i = 2; i <= num; ++i){
            if(is_prime[i]){ // 遍历筛选好的质数
                if(sum + i <= num){
                    sum += i;
                    count++;
                    cout << i << endl;
                }else{
                    break; // 累加超界,直接退出
                }
            }
        }
        cout << "质数个数:" << count << endl;
    }
    return 0;
}

评论

  1. 91岁老太太
    7 小时前
    2026-1-11 18:42:47

    一般般

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇