欧几里得算法
取模运算的运算规则
(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
又名辗转相除法
代码实现过程
1非递归写法
int gcd(int a,int b)
{
int r=a%b;
while(r)
{a=b;
b=r;
r=a%b;
}
return b;
}
2递归写法
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
最小公倍数lcm(a,b)=ab/gcd(a,b)
最大公约数和最小公倍数的一些性质
gcd(a , b) = gcd(b , a-b)
gcd(ma , mb) = mgcd(a , b), m为一个自然数
gcd(a+mb , b) = gcd(a , b)
m=gcd(a , b) 则gcd(a/m,b/m)=gcd(a,b)/m
gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c))
lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c))
一.NEFU-992
又见GCD
Problem:B
Time Limit:1000ms
Memory Limit:65536K
Description
有三个正整数a,b,c(0<a,b,c<10^6),其中c不等于b。若a和c的最大公约数为b,现已知a和b,求满足条件的最小的c。
Input
每行输入两个正整数a,b。
Output
输出对应的c,每组测试数据占一行
Sample Input
6 2
12 4
Sample Output
4
8
i每次递增的值设为b即可
#include <bits/stdc++.h>
using namespace std;
int i;
int main()
{
int a,b,c,g;
while(cin>>a>>b)
{
int min=999999;
for(i=b*2;;i+=b)
{
if(__gcd(i,a)==b){min=i;
break;
}}
cout<<min<<endl;
}
return 0;
}
二.NEFU-764
多个数的最大公约数
Problem:C
Time Limit:1000ms
Memory Limit:65536K
Description
给定n(n<=10)个正整数,你的任务就是求它们的最大公约数,所有数据的范围均在long long内。
Input
输入数据有多组,每组2行,第一行为n,表示要输入数字的个数,接下来第二行有n个正整数。
Output
输出一个数,即这n个数的最大公约数。
Sample Input
5
2 4 6 8 10
2
13 26
Sample Output
2
13依次求每两个数的最大公因数即可,类似于斐波那契数列
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n;
while(cin>>n)
{
long long ans=1,i;
long long a[n];
for(i=1;i<=n;i++)
{
cin>>a[i];
}
for(i=1;i<=n-1;i++)
{
a[i+1]=__gcd(a[i],a[i+1]);
}
cout<<a[n-1]<<endl;
}
return 0;
}
三.NEFU-765
多个数的最小公倍数
Problem:D
Time Limit:1000ms
Memory Limit:65536K
Description
给定n(n<=10)个正整数,你的任务就是求它们的最小公倍数,所有数据的范围均在long long内。
Input
输入数据有多组,每组2行,第一行为n,表示要输入数字的个数,接下来第二行有n个正整数。
Output
输出一个数,即这n个数的最小公倍数。
Sample Input
5
2 4 6 8 10
2
13 26
Sample Output
120
26
原理同上一道题
#include <bits/stdc++.h>
using namespace std;
int i;
int main()
{
long long n;
while(cin>>n)
{
long long ans=1;
long long a[n];
for(i=0;i<n;i++)
{
cin>>a[i];
ans=(ans*a[i]/__gcd(ans,a[i]));
}
cout<<ans<<endl;
}
return 0;
}
五.NEFU-1669
高木同学的因子
Problem:G
Time Limit:1000ms
Memory Limit:65535K
Description
今天西片同学又被高木同学捉弄了,高木同学跟西片同学玩了这么一个游戏。两人心中分别想一个数字,这两个数字分别为x和y(1<=x,y<=1e18),然后让西片同学说出一共有多少个整数既是x的因子,又是y的因子。由于西片和高木很有默契,所以保证他们两个想的数x和y的最大公因数不会超过1e9。这个问题又难住了西片同学了,你能帮帮西片同学告诉他答案吗?
Input
单组输入
数据占一行,包含两个整数x和y(1<=x,y<=1e18),保证gcd(x,y)<=1e9。
Output
输出既是x因子又是y因子的整数的个数。输出占一行
Sample Input
12 36
Sample Output
6
因为x和y都是很大的数字,直接暴力计算不可取,两个数的公因子中的最大值应为最大公因数,其他因子都为最大公因子的因子,因此将问题转化为求最大公因子的因子个数。
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long x , long long y)
{
if(y == 0) return x;
else return gcd(y , x % y);
}
int main()
{
long long m,n,i;
cin>>m>>n;
int daan=0;
long long q=gcd(m,n);
for(i=1;i*i<q;i++) //只判断一半
{
if(q%i==0)daan+=2; //此处每次加上2,因为循环条件判断的是一半,每次加一对数
}
if(i*i==q)daan++;
cout<<daan<<endl;
return 0;
}
来源:CSDN
作者:abysswatcher_1
链接:https://blog.csdn.net/abysswatcher1/article/details/103911326