素数筛选法与点灯案例

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、素数筛选法

1.介绍:假设所有待判断的数字的上限是L,声明一个长度为L+1的布尔数组A[L+1]。用这个数组来表示对应下标的数字是不是素数。起初,将数组所有成员标记为1,然后按照某种方法将其中的非素数都标记为0即可

2.实现:
(1)首先声明一个布尔数组isprime[L+1], 先将isprime[0],isprime[1]置0,再将布尔数组里所有除了2以外的偶数判断元素置false,这样我们判断的数据就减少了一半。
(2)从i = 3开始,将小于等于L 的每一个j = i*i的奇数倍的isprime[j]置0;筛去所有素数的倍数,剩余则为素数。

3.代码:

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

#define MAXN 100

int prime[MAXN] = {0};//素数表
bool is_prime[MAXN + 1] = {0};

int Sieve(int n)
{
    int p = 0;
    int index = 0;

    is_prime[0] = is_prime[1] = false;
    is_prime[2] = true;
    for (index = 3; index <= n; index += 2) //奇数置ture
    {
        is_prime[index] = true;
    }
    prime[0] = 2;
    for (index = 3; index <= n; index += 2)
    {
        if (is_prime[index])
        {
            prime[++p] = index;
            for (int i = index * index; i <= n; i += index * 2)
            {
                is_prime[i] = false;
            }
        }
    }
    return p + 1;
}

int main(int argc, char const *argv[])
{
    int all_num = 0;

    all_num = Sieve(20);
    printf("素数个数:%d\r\n", all_num);
    for (int i = 0; i < all_num; i++)
    {
        printf("%d ", prime[i]);
    }
    printf("\r\n");
    return 0;
}

结果:

素数个数:8
2 3 5 7 11 13 17 19

二、点灯案例

1.案例

有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯编号。k≤n≤1000
输入 输入一组数据:n和k
输出 输出开着的灯编号

2.思路

此案例与素数筛选法有些相似,设每个灯一开始的状态为false,从第i = 0个人开始,直到i < k, 将每个 i 的倍数取反,看每个灯取反多少次即得其最终状态。

3.代码

#include <stdio.h>
#include <stdbool.h>

int PrintfState(int n, int k)
{
    int num = 1;
    int person = 1;
    bool state = false;

    for (num = 1; num <= n; num++)
    {
        state = false;
        for (person = 1; person <= k; person++)
        {
            if (!(num % person))
            {
                state = !state;
            }
        }
        if (state)
        {
            printf("%d ", num);
        }
    }
    printf("\r\n");
    return 0;
}

int main(int argc, char const *argv[])
{
    int n = 0, k = 0;
    printf("请输入参数:");
    scanf("%d,%d", &n, &k);
    printf("亮灯编号:");
    PrintfState(n, k);
    return 0;
}

运行:

请输入参数:8,4
亮灯编号:1 4 5 6 7 8
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值