试除法求质数
质数是在大于一的整数中,只能被1 和 它本身整除的数,也叫素数。
时间复杂度为O(sqrt(n))
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, x;
cin >> n ;
while(n -- )
{
int flag = 0;
cin >> x;
if(x < 2 ) cout << "No" << endl;
else
{
for(int i = 2 ; i <= x / i; i++ )
{
if(x % i == 0)
{
flag = 1;
cout << "No" <<endl;
break;
}
}
if(flag == 0)
cout << "Yes" <<endl;
}
}
}
分解质因数
分解质因数就是把一个合数拆分成== 质因子x 质因子== 的形式。
输出样例中
2 1
3 1//以指数和底数的形式体现,2*3=6
空行
2 3 //2 的三次方
是要以底数和指数的形式(a^n)输出,一定要理解。
#include<iostream>
#include<algorithm>
using namespace std;
void divide(int n)
{
for(int i = 2; i <= n / i; i ++)
{
if(n % i == 0)//i 是 n 的因子
{
int s = 0;
while(n % i == 0)
{
n /= i;
s ++ ;
}
cout << i <<" "<< s << endl;
}
}
if(n > 1) cout << n << " "<< 1 << endl;
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
while(n -- )
{
int x;
cin >> x;
divide(x);
}
return 0;
}
埃式筛法
埃式筛法是一种古老而简单的方法,可以快速找到 [2, n] 内的所有的素数,对于初始{2,3,4,5,6,7,8,9,10,11,12,13,… , n}:
(1)输出最小素数2,然后筛掉2的倍数。
(2)输出最小素数3,然后筛掉3的倍数。
(3)输出最小素数5,筛掉5的倍数。
以此类推,直到队列为空。
算法时间复杂度为O(nloglogn)
#include<iostream>
using namespace std;
const int N = 1000010;
int prime[N], cnt;
bool st[N];//默认false ,是质数就是false,不是为true
void get_prime(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i])//i 是质数
{
prime[cnt ++ ] = i;//是质数就计1
for(int j = i + i; j <= n; j += i )
st[j] = true; //筛除 i 的倍数
}
}
}
int main()
{
int n;
cin >> n;
get_prime(n);
cout << cnt <<endl;
return 0;
}
埃式筛法限制条件是n <= 10^7
线性筛法
思想是:n只会被最小质因子筛掉
时间复杂度O(n)
#include<iostream>
using namespace std;
const int N = 1000010;
int prime[N], cnt;
bool st[N];//默认false ,是质数就是false,不是为true
void get_prime(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i]) prime[cnt ++ ] = i;//i 是质数
for(int j = 0; prime[j] <= n / i; j ++ )
{
st[prime[j] * i] = true;//将i的倍数记为不是质数
if(i % prime[j] == 0) break; //prime[j]一定是i的最小质因子
}
}
}
int main()
{
int n;
cin >> n;
get_prime(n);
cout << cnt <<endl;
return 0;
}
线性筛法会更快一些。