1 条题解

  • 0
    @ 2025-5-5 21:40:53

    题意分析

    对于每个输入正整数 $n$($2 \le n \le 10000$),统计有多少种方法将它表示为一个或多个连续质数之和。


    解题思路

    1. 先用埃氏筛预处理出所有不超过 10000 的质数,存入数组 primes。

    2. 对于每个目标值 nn,使用双指针(滑动窗口)在 primes 上维护区间和:

      • 用左右指针 L,RL,R 和当前和 SS,初始 L=0,R=0,S=0L=0,R=0,S=0
      • S<nS < nR<primesR<|\text{primes}| 时,S+=primes[R++]S += \text{primes}[R++]
      • S=nS = n,答案计数加 1;
      • 然后将 S=primes[L++]S -= \text{primes}[L++],继续上述过程,直到 S<nS < n 且无法扩展。

    本题代码

    #include <cstdio>
    #include <vector>
    using namespace std;
    
    vector<int> primeVector;
    void sievePrimes() {
        const int MAXV = 10000;
        static bool isPrime[MAXV+1];
        for (int i = 2; i <= MAXV; i++) isPrime[i] = true;
        for (int i = 2; i*i <= MAXV; i++) {
            if (!isPrime[i]) continue;
            for (int j = i*i; j <= MAXV; j += i)
                isPrime[j] = false;
        }
        for (int i = 2; i <= MAXV; i++) {
            if (isPrime[i])
                primeVector.push_back(i);
        }
    }
    
    int num;
    void solve() {
        int count = 0;
        int sum = 0;
        size_t left = 0, right = 0;
        while (true) {
            while (sum < num && right < primeVector.size()) {
                sum += primeVector[right++];
            }
            if (sum < num) break;
            if (sum == num) count++;
            sum -= primeVector[left++]; 
        }
        printf("%d\n", count);
    }
    
    int main() {
        sievePrimes(); 
    
        while (scanf("%d", &num) == 1 && num) {
            solve();
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1739
    时间
    1000ms
    内存
    64MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者