ACM — 数论 — 素数

版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/82077779

1.啥是素数啊?啦

小学知识点吧同志,百度词条官方定义:

质数(prime number)又称素数,有无限个。

质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数

(与之相对的,自然就是合数啦)

2.素数的一些性质(持续更新)

1.质数的约数只有一和他本身。

2.唯一分解定理 : 一个大于1的整数一定可以被分解成若干质数的乘积

这个其实不必证明,任意一个数,如果本身是素数,那分解后就是他本身了;如果是合数,那他必然有除一和本身外别的约数,而这些约数或者是素数,或者又是合数,所以呢?往下分解不就成了,最终难道不是素数吗?你再想想吧,小帅逼。

以一个炒鸡简单的题为例:

假设x是一个正整数,请编写一个程序,将x分解为若干个素数的乘积。

#include <bits/stdc++.h>     
using namespace std;
int num[10000],c,n,t; 
int main()    
{    
       
    scanf("%d",&t);   //t组测试数据 
    while(t--)    
    {    
        scanf("%d",&n);    
        c = 0;  
        for(int i = 2; i < = n; i++)
        {    
            while(n%i==0)//有了这个循环 就不必求素数表了,为啥呢,自己想啊
            {    
                num[c++]=i;
                n/=i;
            }    
        }    
        for(int i = 0; i < c; i++)    
        {    
            printf(i==0?"%d":"*%d",num[i]);    
        }    
        printf("\n");    
    }    
    return 0;    
}

(待更新)

3.判断素数

定义判断是否有多余的因数即可即可,但是你认为需要从1判断到这个数本身吗?

当然不必,判断到\sqrt{x}即可,为什么呢,因为大于\sqrt{x}的数根本不可能被整除。

代码:

//判断是否是一个素数
int IsPrime(int x)
{
        if(x<=1)    //0,1,负数都是非素数 
        return 0;
        int ans=(int)sqrt(x)+1;     /*计算枚举上界,为防止ans值带来的精度损失,所以采用根号值 
                                        取整后再加1,即宁愿多枚举一个,也不愿少枚举一个数 */
        for(int i=2; i<ans; i++)
        {
          if(x%i==0)
          {
            return 0;//只要一个被整除,就不是素数
          }
        }
         return 1;
}

4.素数筛法:

先开一个比较大的数组prime[ ]奇数下标的标为true(1除外),偶数下标标为false(2除外)

for( i=3; i<=sqrt(n); i+=2 )
{ 
       if(prime[i])
       for( j=i+i; j<=n; j+=i )//素数的任意倍数都必然是合数
       prime[j]=false;
 }

线性筛法:

/*
遇到素数需要打表时,先估算素数的个数:
num = n / lnx;
num为大概数字,越大误差越小(只是估计,用于估算素数表数组大小)
线性筛法wwwww
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 10010000
int n;
bool visit[maxn];
int prime[maxn];
void isprime()
{
    memset(visit, true, sizeof(visit));
    int num = 0;
    for (int i = 2; i <= n; ++i)
    {
        if (visit[i] == true)
        {
            num++;
            prime[num] = i;
        }
        for (int j = 1; ((j <= num) && (i * prime[j] <= n));  ++j)
        {
            visit[i * prime[j]] = false;
            if (i % prime[j] == 0) break; //深究之处!
        }
    }
}
int main()
{
    memset(prime, 0, sizeof(prime));
    int count= 0;
    scanf("%d",&n);
    isprime();
    for(int i = 0; i <= n; ++i)
        if(prime[i])
        {
            printf("%d ",prime[i]);
            count++;
        }
    printf("\n");
    printf("the sum of prime num is:%d\n",count);
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/Healer66/article/details/82077779
今日推荐