7-294 筛法求素数

素数是仅仅能被它本身和1整除的任何整数。筛法求素数是一种查找素数的方法。它的算法如下:

1、创建一个数组,并将所有元素初始化为1(真)。具有素数下标的数组元素将保持为1,而其它数组元素最终将被设置为0。

2、从数组下标2开始,每次找到一个值是1的数组元素时,在数组的剩余部分中循环,并将值为1的元素的下标整数倍的所有元素设置为0。对于数组下标2,数组中所有2以上的而且是2的整数倍的元素都将这是为0(下标4、6、8、10等等)。对于数组下标3,数组中所有3以上,而且是3的整数倍的元素都将设置为0(下标6、9、12、15等等)。

当这个过程结束时,仍然为1的数组元素的下标是一个素数。然后就可以输出这些素数。

编写一个程序,输出区间[m, n]之间的所有素数。

输入格式:

输入的第一行是一个整数k,表示以后会有k次查询。
后面的k行中,每行2个整数m和n。

输入保证 2 <= m <= n <= 100000。

输出格式:

对每一行的m和n,把闭区间[m, n]之间的所有素数输出到一行。每个数之间以空格隔开。若区间内没有素数,输出None

输入样例:

6
2 20
3 3
5 15
11 32
121 126
100 200

输出样例:

在这里给出相应的输出。例如:

2 3 5 7 11 13 17 19 
3 
5 7 11 13 
11 13 17 19 23 29 31 
None
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 

代码长度限制

16 KB

时间限制

250 ms

内存限制

64 MB

首先,定义一个大小为max(100000)的数组is_prime,用于标记每个数是否为素数。初始化时,将数组中的所有元素都设置为1,表示假设所有数都是素数。

然后,使用筛法来找出素数。从2开始遍历到sqrt(max)(也就是i*i<max),对于每个素数i,将它的倍数j(j=i, i+i, i*i+2i, ...)标记为非素数。通过将is_prime[j]设置为0来标记非素数。

最后,输入k,然后进行k次查询。对于每次查询,输入查询区间[m, n],遍历该区间内的每个数,如果该数在is_prime数组中标记为素数,则输出它,并将flag标记为1。如果整个区间内没有素数输出,则输出"None"。

代码

#include<stdio.h>
#define max 100000

int main()
{
    int k, i, j, is_prime[max];
    scanf("%d", &k);

    // 初始化is_prime数组,假设所有数都是素数
    for (i = 2; i < max; i++)
    {
        is_prime[i] = 1;
    }

    // 使用筛法求素数
    for (i = 2; i * i < max; i++)
    {
        if (is_prime[i])
        {
            // 标记i的倍数为非素数
            for (j = i * i; j < max; j += i)
                is_prime[j] = 0;
        }
    }

    while (k--)
    {
        int m, n;
        int count_prime = 0;
        scanf("%d%d", &m, &n);

        // 遍历区间内的每个数,判断是否为素数
        for (i = m; i <= n; i++)
        {
            if (is_prime[i])
            {
                printf("%d ", i);
                count_prime = 1;
            }
        }

        // 如果区间内不存在素数,输出"None"
        if (!count_prime)
        {
            printf("None");
        }
        printf("\n");
    }

    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾乃宇宙欠债王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值