方法一:暴力
时间复杂度O(n * sqrt(n))
include<stdio.h>
int is_prime(int x)
{
for (int i=2; i*i < x; i++)
if (x % i == 0)return 0;
return 1;
}
int main()
{
int num,prime_num = 0;
for (num = 1; prime_num<= 1001;)
{
num++;
prime_num += is_prime(num);
}
printf("%d
",num);
return 0;
}
方法二:素数筛
时间复杂度O(n * sqrt(loglogn))
总体思想:素数的倍数一定是合数,用已知的素数标记合数
#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000
int prime[MAX_N + 5] = {0};
int main()
{
for (int i = 2; i <= MAX_N; i++){
if (!prime[i]){
for (int j = 2*i; j<MAX_N; j += i){
prime[j] = 1;
}
}
}
for (int i = 2; i <= MAX_N; i++)
if(!prime[i]) prime[++prime[0]] = i;
int n;
while (~scanf("%d",&n))
{
printf("第%d个素数是%d
",n,prime[n]);
}
}
变形一:求1-1000内每个数字最小的素因子
#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000
int prime[MAX_N + 5] = {0};
int main()
{
for (int i = 2; i*i <= MAX_N; i++){
if (!prime[i]){
for (int j = i; j <= MAX_N; j += i){
if (!prime[j]) prime[j] = i; ///只有第一次赋值,保证最小
}
}
}
int n;
while (~scanf("%d",&n))
{
printf("%d的最小素因子是%d
",n,prime[n]);
}
}
变形·二:求1-1000内每个数字最大的素因子
#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000
int prime[MAX_N + 5] = {0};
int main()
{
for (int i = 2; i*i <= MAX_N; i++){
if (!prime[i]){
for (int j = i; j <= MAX_N; j += i){
prime[j] = i;/// 覆盖
}
}
}
int n;
while (~scanf("%d",&n))
{
printf("%d的最大素因子是%d
",n,prime[n]);
}
}
方法三:线性筛
时间复杂度O(n )
总体思想:
线性筛是基于素数筛的改进,
在素数筛的时候
6被2标记后,又被3标记...
15被3标记后,又被5标记...
30被2标记后,又被3标记,又又被5标记...
会有重复标记造成的浪费
线性筛的时候
M 为遍历数的代表
Min_p (M) 为M的最小素因子
Set_p (n) 为从2到n的素数集合
第一层循环是:遍历M
第二层循环是:遍历这个Set_p (Min_p (M))的集合元素
eg:
M == 15
Min_p (M) == 3
Set_p (Min_p (M)) = {2,3}
标记的数为:30,45
75 会是 它最小的素因子5 在M为25 时标记到的
#include<bits/stdc++.h>
using namespace std;
#define MAX_N 000
int set_prime[MAX_N + 5] = {0};
int main()
{
for (int m = 2; m <= MAX_N; m++)
{
if (!set_prime[m]) set_prime[++set_prime[0]] = m;
for (int j = 1; j <= set_prime[0] && set_prime[j] * m <= MAX_N; j++)
{
set_prime[set_prime[j] * m] = 1;
if (m % set_prime[j] == 0) break;///功能:保持 prime[j] 一定小于 i 的最小素因子
}
}
int n;
while (~scanf("%d",&n))
{
printf("第%d个的素数是%d
",n,set_prime[n]);
}
}