素数判断(包教包会)

素数判断

素数题,是蓝桥杯常考题型之一,下面就跟我来学习素数的几种常见写法把。

素数(也叫质数):指在大于1自然数,除了1和该数自身外,无法被其他自然数整除的数 (也可定义为只有1与该数本身两个正因数的数)。大于1的自然数若不是素数,则称之为合数(也称为合成数),其中根据定义数字2,就是最小的素数

一、暴力写法

题目:判断数字n,是不是质数

如果暴力直接写的话,直接根据定义判断从2~n-1,没有可以被n整除的数,那么n就是质数了。

代码如下:

#include<bits/stdc++.h>
using namespace std;

int n;
bool flag = true;

int main(){
    cin >> n;
    for(int i = 2; i < n; i++){
        if (n % i == 0){//n与i的余数为零,即代表可以整除
            flag = false;
            break;
        }
    }
    cout << (flag ? "n 是素数" : "n 不是素数");//三目运算 flag 为真执行 :前面的语句,反之执行后面的语句
}

二、试除法(暴力的优化)

题目:还是一样的

原理:此一程序将n除以每个大于1且小于等于的平方根之整数m,若存在一个相除为整数的结果,则n不是素数;反之则是个素数。实际上,若是个合数(其中与b!=1),则其中一个约数b必定至大为 n \sqrt{n} n

简而言之:就是原来判断2~ n-1,现在判断2~ n \sqrt{n} n

代码如下:

#include<bits/stdc++.h>
using namespace std;

int n;
bool flag = true;

int main(){
    cin >> n;
    for(int i = 2; i*i < n; i++){ //也可以写成i < pow(n,0.5),写成这样怕你们看不懂(狗头)
        if (n % i == 0){//n与i的余数为零,即代表可以整除
            flag = false;
            break;
        }
    }
    cout << (flag ? "n 是素数" : "n 不是素数");//三目运算 flag 为真执行 :前面的语句,反之执行后面的语句
}

三、埃式筛法(也称素数筛)

题目:还还是一样的

原理:所使用的原理是从2开始,将每个质数的各个倍数,标记成合数

按我的理解:素数的倍数一定不是质数,因为,因为他的倍数可以被,当前的素数整除呀!所以,简而言之,素数的倍数不是素数,把这些,不是素数去掉就OK了

代码如下:

#include<bits/stdc++.h>
using namespace std;

const int maxl = 1e5+5;

int n;
bool flag[maxl];

int main(){
    memset(flag, 1, sizeof(flag));
    cin >> n;
    for (int i = 2; i <= n; i++){
        if (flag){
            for (int j = 2 * i; j <= n; j += i){//这里把每个质数i的倍数给去掉(flag[j]变成false)
                flag[j] = false;
            }
        }
    }
    cout << (flag[n] ? "n 是素数" : "n 不是素数");//三目运算 flag 为真执行 :前面的语句,反之执行后面的语句
}

四、欧拉筛

题目:还是一样

原理:用已知的质数筛掉这个质数的倍数。且需要保证对于任意一个合数,它会且只会它的最小因数筛掉

简而言之:欧拉比埃式筛法是它不会重复标j记一个数是不是素数的倍数

代码如下:

#include<bits/stdc++.h>
using namespace std;
bool flag[100001]={1,1};//i=0,i=1的时候都不是质数 ,所以直接标记
int b[100001], n;//b存质数 
int k;

int main(){
	cin>>n;
	for(int i = 2;i <= 100001;i++){
		if (!flag[i]){
             b[++k]=i;
        }
		for(int j = 1;j <= k;j++){
			if(i * b[j] > 100001)break;// 如果超出给出的范围,那么就退出循环 
			a[i * [j]] = 1;//用质数数依次×i,结果标记为合数(也就是标记为1)。 
			if(i % b[j] == 0)break;//最关键的只标记一次 
		}	
	}
	cout << (flag[n] ? "n 是素数" : "n 不是素数");//三目运算 flag 为真执行 :前面的语句,反之执行后面的语句	
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值