1. 质数的判定
算法过程:
- N小于2,返回false
- i从2枚举到 n / i,如果n % i == 0 说明有余数, 返回false
- 全都通过返回true。
代码:
bool is_prime(int n)
{
if(n<=1) return false;
for(int i=2; i <= n/i; i++)
{
if(n % i == 0) return false ;
}
return true;
}
2. 分解质因数
算法过程:
- 从2开始枚举所有的因数,到n / i
- 如果n % I == 0, 使用while循环将该质数除尽,并累加数量
- 如果最后n > 1,输出这个唯一一个大于√n的质因子。
代码:
void divide(int x)
{
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
{
int s = 0;
while (x % i == 0) x /= i, s ++ ;
cout << i << ' ' << s << endl;
}
if (x > 1) cout << x << ' ' << 1 << endl;
cout << endl;
}
3. 筛质数(朴素筛法)
算法过程:
- i从2循环到n
- 如果该数是质数,从i+i到n筛掉所有该质数的合数
void get_primes()
{
for(int i = 2; i <= n; i++)
{
if(!st[i])
{
p[cnt++] = i;
for(int j = i + i; j <= n; j += i) st[j] = true;
}
}
}
4. 筛质数(线性筛法)
- I从2循环到n
- 如果是质数,加入到质数列表中
- 从小到大枚举所有质数到n / I, 筛掉primes[j] * i,当primes[j]是i的最小质因子时break。
成立的原理:
每个合数,均是由最小的质因子primes[j]筛掉的,理由如下:当pj 是i的最小质因数时break,保证pj 是pj * i的最小质因数;当未被break时,pj即小于i的最小质因子。综上全集,合数一定是被最小质因子pj筛掉的。又由于每个合数一定存在最小质因子,且当i枚举到I / pj的时候就被筛掉了,每个合数只被筛了一遍,所以是线性的。
代码:
void get_primes()
{
for(int i = 2; i <= n; i++)
{
if(!st[i]) p[cnt++] = i;
for(int j = 0; p[j] <= n / i; j++)
{
st[p[j] * i] = true;
if(i % p[j] == 0) break;
}
}
}
代码模板转自:Acwing网站