目录
质数/素数定义
在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数,或者叫素数
判断素数(试除法)
约数有一个重要的性质:
假设n代表数字,d代表n的一个约数
即d能整除n(d|n)
那么n/d为n的另外一个约数
即n/d能整除d(n/d | n)
简单思路:
模板:
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;
}
866. 试除法判定质数
代码展示:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
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;
}
int main()
{
int n;
cin >> n;
while (n --)
{
int a;
cin >> a;
if (is_prime(a)) puts("Yes");
else puts("No");
}
return 0;
}
分解质因数(试除法)
从小到大枚举所有的数
为什么不需要判断是否为质因子?
因为i是n的因子,即n是i的倍数,当枚举的到i时,n中已经不包含有2~i-1的因子,即i中也不包含,2~i-1的因子,所以i是质数
n中最多只包括一个大于sqrt(n)的质因子
如果最后剩下一个大于1的数,那就是大于sqrt(n)的质因子
模板:
void divide(int n)
{
for (int i = 2; i <= n / i; i ++ )
{
if (n % i == 0)
{
int cnt = 0;
while (n % i == 0)
{
cnt ++;
n /= i;
}
printf("%d %d\n", i, cnt);
}
}
if (n > 1) printf("%d %d\n", n, 1);
printf("\n");
}
acwing 867. 分解质因数
代码展示:
#include <iostream>
#include <algorithm>
using namespace std;
void divide(int n)
{
for (int i = 2; i <= n / i; i ++ )
{
if (n % i == 0)
{
int cnt = 0;
while (n % i == 0)
{
cnt ++;
n /= i;
}
printf("%d %d\n", i, cnt);
}
}
if (n > 1) printf("%d %d\n", n, 1);
printf("\n");
}
int main()
{
int n;
scanf("%d", &n);
while (n --)
{
int a;
scanf("%d", &a);
divide(a);
}
return 0;
}
埃氏筛法
算法思路:
模板:
void gets_prime(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
cnt ++;
for (int j = i * 2; j <= n; j += i) st[j] = true;
}
}
}
868. 筛质数
代码展示:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1000010;
bool st[N];
int cnt;
void gets_prime(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
cnt ++;
for (int j = i * 2; j <= n; j += i) st[j] = true;
}
}
}
int main()
{
int n;
cin >> n;
gets_prime(n);
cout << cnt << endl;
}
线性筛(欧拉筛法)
算法思路:
模板:
void oula(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}
868. 筛质数
代码展示:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010;
int primes[N];
bool st[N];
int cnt;
void oula(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}
int main()
{
int n;
cin >> n;
oula(n);
cout << cnt << endl;
}