(P3912)素数个数题解

这里附上题目链接:P3912 素数个数

								~~手动分割~~ 

题目

在这里插入图片描述

思路解析

  • 选用合适的素数筛法筛出区间[ 1,n ]的质数并计数,最后输出计数结果即可。

使用筛法需要开一个标记数组visit[ ]。因为题目有125.00MB的内存限制且此题数据范围较大,所以若将数组visit[ ]设为int型,将不能通过测试数据的最后两个点#9和#10。

在使用int型时,所耗内存100000000*4byte = 400000000 byte = 390625 kb = 381.46 Mb在这里插入图片描述
在这里插入图片描述 所以为了减小内存,可将数组visit[ ]定义为布尔型。一个bool变量只占一个byte。

1.欧拉筛法+布尔型变量标记(bool)

AC代码

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

int n,sum;//n为右界
int prime_permutation[1000000];
bool visit[99000000];//visit[i]=true说明i不是质数

int euler_sieve(int n)//n为右界
{
    int i,j;
    visit[0]=true;
    visit[1]=true;//0和1不是素数
    for(i=2;i<=n;i++)
    {
        if(!visit[i])//若i为素数
        {
            prime_permutation[sum]=i;
            sum++;
        }
        for(j=0;j<sum&&(i*prime_permutation[j]<=n);j++)
        {
            visit[i*prime_permutation[j]]=true;
            if(i%prime_permutation[j]==0)
            {
                break;
            }
        }
    }
    return 0;
}

int main()
{
    //输入数据
    scanf("%d",&n);
    //筛选素数
    euler_sieve(n);
    //输出结果
    printf("%d",sum);
    return 0;
}

在这里插入图片描述

2.埃氏筛法+布尔型变量标记(bool)

AC代码

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

int n,sum;//n为右界,sum为数组prime_permutation的计数器
int prime_permutation[1000000];
bool visit[99000000];//visit[i]=true说明i不是质数

//埃氏筛法
int eratosthenes_sieve(int n)//n为右界
{
    int i,j;
    sum=0;
    memset(visit,0,sizeof(visit));//先将标记数组清零
    visit[0]=1;
    visit[1]=1;//0和1不是素数
    for(i=2;i<=n;i++)
    {
        if(!visit[i])//若i为质数
        {
            prime_permutation[sum]=i;//将i存入数组
            sum++;
            for(j=2*i;j<=n;j+=i)//质数i的整数倍一定不是质数
            {
                if(!visit[j])
                {
                    visit[j]=1;
                }
            }
        }
    }
    return 0;
}

int main()
{
    //输入数据
    scanf("%d",&n);
    //筛选素数
    eratosthenes_sieve(n);
    //输出结果
    printf("%d",sum);
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值