质数,最大公约数等等和处理数字有关的题目会经常出现在算法题中。对于常见的处理方式,应该背一个最优解的模板。
1.求最大公约数
最大公约数:也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。
在实际做题时,辗转相除法(欧几里得算法)是最大公约数的一种常用的求法
由于(a,b)=(b,a%b)
能使用如下算法计算最大公约数
int gcd(int a,int b)
{
return b ? gcd(b ,a % b) : a;
//0和任何数的最大公约数都是它本身
//如果b是非零,就返回gcd(b ,a % b)
}
例:
等差数列
原题链接:Acwing.1246
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int q[N];
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++) scanf("%d", &q[i]);
sort(q, q + n);
/*
如果这是一个等差数列,将q数组排序之后,一定能将各项表示为 a+k1b a+k2b ... a+knb
那么项数就为(a末-a初)/d + 1
为了使得上述得数列最短,就需要使(a末-a初)尽可能地小,d尽可能地大
a末的最小值是q[n-1]
a初的最大值是q[0]
d的最大值是各项与首项的差的最大公约数
*/
int d = 0;
for (int i = 0; i < n; i++)
d = gcd(d, q[i]-q[0]);
if (d == 0)
printf("%d\n",n);
else
printf("%d",(q[n - 1] - q[0]) / d + 1);
}
筛法求素数
质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
int prime[N],cnt; //存所有素数
bool st[N]; //当前数有没有被筛过
int min[N];
int get_primes(int n)
{
for(int i=2;i <= n;i ++)
{
if(!st[i]) minp[i]=i,primes[cnt++]=i;
for(int j=0;primes[j]*i<=n;j++)
{
st[primes[j]*i]=true;
minp[primes[j]*i]=primes[j]
if(i%primes[j]==0) break;
}
}
}
质数与合数
质数与合数是针对从2开始的整数定义的
质数:在大于1的整数中,如果只包含1和本身这两个约数,就被成为质数或者叫素数
(1) 质数的判定:试除法
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n / i; i++)
if (n % i == 0)
return false;
return true;
}
需要注意的点: 使用 i <= n / i 能加快处理速度,同时防止出现溢出
分解质因数
试除法