HDU1319 Prime Cuts

问题链接:HDU1319

这是一个比较简单的问题。其关键是需要读懂题意,使用素数筛选法打表,然后进行输出即可。

需要注意的点如下:

1.题目中所说的素数并不是真正的素数,包括1;

2.需要读懂题意,对于输入的n和c,如果1到n之间有偶数个素数则打印2c个数,奇数个素数则打印2c-1个数;

3.打印的数是所有素数中位于中间位置的那些数。

事先还是要做一点功课的,计算一下1到1000之间有多少个素数,避免数组空间过大或过小。

另外,题目虽然说n<=100,但是,至少需要算一个比1000大的素数,以便统计小于n的素数的个数。

本程序逻辑清晰易懂,计算过程参见程序注释。

程序如下:

/* HDU1319 PKU1595 Prime Cuts */

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

using namespace std;

#define MAXN 1050

bool isprime[MAXN+1];
int prime[200];

// 修正的Eratosthenes筛选法,根据题意包含1(并非全是素数)
void sieveofe(bool isprime[], int prime[], int n)
{
    int i, j;

    isprime[0] = false;
    isprime[1] = true;
    isprime[2] = true;

    // 初始化
    for(i=3; i<=n; i++) {
        isprime[i++] = true;
        isprime[i] = false;
    }
    int max = sqrt(n);
    for(i=3; i<=max; i++){
        if(isprime[i]) {
            for(j=i+i; j < n; j+=i)    //进行筛选
                isprime[j] = false;
        }
    }

    // 将素数放数组prime中,包含1
    prime[0] = 1;
    prime[1] = 2;
    j = 2;
    for(i=3; i<=n; i+=2)
        if(isprime[i])
            prime[j++] = i;
}

int main()
{
    // 筛选素数
    sieveofe(isprime, prime, MAXN);

    int n, c, count, i;
    int printcount, start, end;

    // 循环处理输入
    while(~scanf("%d%d",&n,&c)) {
        printf("%d %d:", n, c);

        // 统计素数个数
        count = 0;
        i = 0;
        while(prime[i++] <= n)
            count++;

        // 计算打印数据的个数
        if(count % 2 == 0) {
            printcount = 2 * c;
        } else {
            printcount = 2 * c -1;
        }

        // 计算数据的起始与终止位置
        if(printcount >= count) {
            start = 0;
            end = count - 1;
        } else {
            start = (count - printcount) / 2;
            end = start + printcount - 1;
        }

        // 打印结果
        for(i=start; i<=end; i++)
            printf(" %d", prime[i]);
        printf("\n\n");
    }

    return 0;
}


你可能感兴趣的:(素数,ICPC,筛选)