数学知识之质数

质数:

质数也称素数,指的是在大于1的自然数中,因数只有1和它本身的数。

如何判断一个数是否为质数:

试除法

时间复杂度O(sqrt(n))。如果一个数有除了1和自身之外的因数,那么必定有一个因数是小于等于根号n的,反之,如果在根号n到n之间没有因数,那么他一定没有因数。所以我们只需要对1~sqrt(n)进行试除即可。

代码如下:

bool is_prime(int x) {
	for (int i = 2; i <= x / i; i++)
		if (x % 2 == 0)return false;
	return true;
}

分解质因数:

每个合数都可以写成几个质数相乘的形式。x=a^an * b^bn * ......

先说做法:假设要分解x,我们枚举2~sqrt(x),如果能找到因数k,就一直除以这个因数直到除完,假如除以k了n次,那么k^n就是分解出的一项,最后判断x是否大于1,如果大于1,这时的x也是一个因数,此时x就被分解完了。

再说解释:为什么是枚举2~sqrt(x)并且最后判断x是否大于1呢,因为x最多只有一个大于sqrt(x)的因数,所以枚举到sqrt(x)即可,最后特判x是否有一个大于sqrt(x)的因数即可,x大于1的话就证明剩下的这个数就是x的大于sqrt(x)的因数。为什么是枚举2~sqrt(x)内得所有数而不是质数呢,因为x有合数因数k的话,x就会在枚举到k之前将k这个合数因数分解成若干质数的形式。

代码如下:

void get_primes(int x) {
    for (int i = 2; i <= x / i; i++) {//枚举2~sqrt(x)
        if (x % i == 0) {//如果是因数
            int s = 0;//i的k次方
            while (x % i == 0) {
                s++;
                x /= i;
            }
            cout << i << " " << s << endl;
        }
    }

    if (x > 1)cout << x << " 1" << endl;//检查是否有大于sqrt(x)的因数
    return;
}

质数筛:

将一个区间内的所有质数筛选出来。

筛选出小于等于n的所有质数。我们从前往后枚举所有数,每枚举到一个数,就以这个数为因数,将其后面的所有倍数记录下来,那么这些数就不是质数。如果枚举到一个数时,这个数没有被记载,那么这个数就是质数。

#include
using namespace std;
const int N=1e6+10;
bool st[N];
int n;

int main(){
    cin>>n;
    int res=0;
    for(int i=2;i<=n;i++){
        if(!st[i])res++;//如果这个数没有被记录过
        for(int j=i;j<=n;j+=i)st[j]=true;//每次加上自身一次,往后找合数
    }
    
    cout<

你可能感兴趣的:(算法,数据结构,蓝桥杯,c++)