ch3(数学)——质数

1.自然语言描述
质数:除了1和它本身之外没有因数的数。
试除法判定质数:根据质数定义,判断这个数能不能被1和它本身之外的数整除;若能则说明这个数不是质数,若不能则这个数是质数。
分解质因数:任意一个合数都可以分解为若干个质数幂相乘的形式。
质数筛:得到2~n之间所有的质数,用一个标记数组st[i]判断i是否是质数。
2.代码描述
题目:Acwing.866 试除法判定质数题目链接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int main(void)
{
    int n;
    
    cin>>n;
    while(n--){
        int x;
        cin>>x;
        
        if(x==1){//1不是质数
            cout<<"No"<<endl;
            continue;
        }
        
        bool flag=true;
        for(int i=2;i<=x/i;i++)//从2枚举到x的最大因子sqrt(n),但因为sqrt(n)执行耗时大,这里换了一种耗时小的写法
            if(x%i==0){//发现了非1和x本身的因子,x不是质数
                flag=false;
                break;
            }
            
        if(flag)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
    
    return 0;
}

题目:Acwing.867 分解质因数题目链接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int main(void)
{
    int n;
    
    cin>>n;
    
    while(n--){
        
        int x;
        cin>>x;
        
        for(int i=2;i<=x/i;i++){//定理:任何一个合数都可以分解为若干个质数幂相乘的形式。
            if(x%i==0){         //因此,每次发现质因子并让x除以这些质因子若干次幂使x去除掉这个质因子
                                //之后枚举到的符合x%i==0条件的一定是另一个质因子。
                int s=0;
                while(x%i==0){//去掉x中质数i的幂
                    x/=i;
                    s++;
                }
                cout<<i<<' '<<s<<endl;//输出质数的底数和指数部分
            }
        }
        if(x>1)
            cout<<x<<' '<<1<<endl;
        cout<<endl;
    }
    
    return 0;
}

题目:Acwing.868 筛质数题目链接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN=1e6+10;

int n,primes[MAXN],cnt;
bool st[MAXN];

//朴素质数筛:如果i是质数则记录,并将当前i的所有2~n之间的倍数筛除
// void calc1()
// {
//     for(int i=2;i<=n;i++){
//         if(!st[i])
//             primes[cnt++]=i;
//         for(int j=2*i;j<=n;j+=i)
//             st[j]=true;
//     }
// }

//埃式筛法:不需要筛除合数的倍数,只筛掉质数的所有2~n之间的倍数
// void calc2()
// {
//     for(int i=2;i<=n;i++){
//         if(!st[i]){
//             primes[cnt++]=i;
//             for(int j=2*i;j<=n;j+=i)
//                 st[j]=true;
//         }
//     }
// }

//线性筛:由于是从小到大枚举,得到的质数也是从小到大的,所以每个数可以被它的最小质因子筛去
void calc3()
{
    for(int i=2;i<=n;i++){
        if(!st[i])
            primes[cnt++]=i;
        for(int j=0;primes[j]<=n/i;j++){//由于是从小到大筛取质数的,每一个数一定会被它的最小质因子筛去
            st[primes[j]*i]=true;//primes[j]小于i的所有质因子,同时primes[j]*i的最小质因子为primes[j]
            if(i%primes[j]==0)//i的最小质因子为primes[j],同时primes[j]*i的最小质因子为primes[j](前一个语句一定筛过了)
                break;//让所有的非质数只被筛一次,故名线性筛
        }
    }
}

int main(void)
{
    cin>>n;
    
    //calc1();
    //calc2();
    calc3();
    
    cout<<cnt<<endl;
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值