UVALive3399 UVA1210 POJ2739 Sum of Consecutive Prime Numbers【素数筛选+尺取法】

509 篇文章 9 订阅
281 篇文章 4 订阅

 

Sum of Consecutive Prime Numbers

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 25286 Accepted: 13793

 

Description

Some positive integers can be represented by a sum of one or more consecutive prime numbers. How many such representations does a given positive integer have? For example, the integer 53 has two representations 5 + 7 + 11 + 13 + 17 and 53. The integer 41 has three representations 2+3+5+7+11+13, 11+13+17, and 41. The integer 3 has only one representation, which is 3. The integer 20 has no such representations. Note that summands must be consecutive prime 
numbers, so neither 7 + 13 nor 3 + 5 + 5 + 7 is a valid representation for the integer 20. 
Your mission is to write a program that reports the number of representations for the given positive integer.

Input

The input is a sequence of positive integers each in a separate line. The integers are between 2 and 10 000, inclusive. The end of the input is indicated by a zero.

Output

The output should be composed of lines each corresponding to an input line except the last zero. An output line includes the number of representations for the input integer as the sum of one or more consecutive prime numbers. No other characters should be inserted in the output.

Sample Input

2
3
17
41
20
666
12
53
0

Sample Output

1
1
2
3
0
0
1
2

Source

Japan 2005

 

 

 

 

 

Regionals 2005 >> Asia - Tokyo

 

问题链接UVALive3399 UVA1210 POJ2739 Sum of Consecutive Prime Numbers

题意简述

  给定一个10000以内的n,判定n是否可以由几个连续的素数(例如:2,3,5,7...)相加得到,输出解的组数。

问题分析

  先用筛选法,筛选出素数备用,然后用尺取法解决。素数是单调递增的,满足用尺取法解决问题的条件。

  先求出最前面的子序列,使之素数和大于或等于n;

  重复后面一步,直到p素数大于n;

  若素数子序列和等于n,则解数计数;去掉子序列的第1个元素,子序列的后面再加上后续素数(只有素数值小于n时才累加),直到子序列和为0(后续素数已经大于n,无法加上,而不断减去第1个元素)。

程序说明

  小于10000的最大素数为9973,如果只用小于等于9973的素数,结果会出问题。需要多算几个素数,筛选出的素数有大于10000的素数就没有问题了。程序中,素数筛选范围是2到10000+10。

 

AC的C++语言程序如下:

/* UVALive3399 UVA1210 POJ2739 Sum of Consecutive Prime Numbers */

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>

using namespace std;

const int N = 10000;
int primes[N+1+10];

// Eratosthenes筛选法
void esieve(int n)
{
    memset(primes, 0, sizeof(primes));

    primes[0] = primes[1] = 1;
    for(int i=2; i<=sqrt(n); i++) {
        if(!primes[i]) {
            for(int j=i*i; j<=n; j+=i)  //筛选
                primes[j] = 1;
        }
    }

    for(int i=2, j=0; i<=n; i++)
        if(!primes[i])
            primes[j++] = i;
}

int main()
{
    esieve(N+10);

    int n;
    while(cin >> n && n) {
        int start, end, sum, ans;
        start = end = sum = ans = 0;
        for(;;) {
            while(primes[end] <= n && sum < n)
                sum += primes[end++];

            if (sum == n)
                ans++;

            sum -= primes[start++];

            if (sum <= 0)
                break;
        }
        printf("%d\n", ans);
    }

    return 0;
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值