取模运算的运算法则
(a+b)%p=(a%p+b%p)%p
(a-b)%p=(a%p-b%p)%p
(a*b)%p=(a%p*b%p)%p
(a^b)%p=((a%p)^b)%p
欧几里得算法(辗转相除法)
欧几里得算法(辗转相除法)是求两个正整数的最大公约数的一种算法。其基本思想是通过反复将两个数中较大的数替换为它们的差,直到两个数相等,此时这个相等的数就是它们的最大公约数。
代码实现
非递归:
int gcd(int a,int b)
{
int t=a%b;
while(t)
{
a=b;
b=t;
t=a%b;
}
return b;
}
递归:
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
拓展至lcm(最小公倍数)
最小公倍数可由最大公约数得到,a,b的最小公倍数记为lcm(a,b)。
lcm(a,b)a*b/gcd(a,b)
但我们一般写为lcm=a/gcd(a,b)*b,这是为了防止a*b溢出。
多个数的情况
例:求n个数的最小公倍数,所有数据的范围均在long long内。
Input
输入数据有多组,每组2行,第一行为n,表示要输入数字的个数,接下来第二行有n个正整数。
Output
输出一个数,即这n个数的最小公倍数。
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return a/gcd(a,b)*b;
}
int main()
{
int n;
while(cin>>n)
{
long long res=1;
for(int i=0;i<n;i++)
{
long long x;
cin>>x;
res=lcm(res,x);
}
cout<<res<<endl;
}
return 0;
}
代码运行结果如下: