最大公约数
最大公约数用到一个算法叫欧几里得算法,也叫辗转相除法。
欧几里得算法
求(a,b)的最大公约数可以转化为(a,a%b)的最大公约数
证明:
译:d能整除a并且d能整除b,d就能整除a+b。并且d就能整除x倍a+b倍y
比如2|4 ,2|6 ,2就可以|(6+4)。
用代码表示为如下:
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
return b?(b,a%b):a;//b不为0就返回(a,a%b),否则就返回a
}
int main()
{
int a=0,b=0;
cin>>a>>b;
cout<<gcd(a,b);
return 0;
}
当然c++也有个求最大公约数的库函数:__gcd(),头文件为
一。首先排个序,然后开个辅助空间。
二.用等差公式 推出来所有的数
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N];
int b[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a,a+n);
int d=a[2]-a[1];
int i=1;
int count=0;
while(i)
{
b[1]=a[1];
b[i+1]=a[1]+(i)*d;
count++;
cout<<b[i]<<" ";
i++;
if(b[i]>20)break;
} cout<<endl;
cout<<count<<" ";
return 0;
}
过了第一个测试样例:
但是第二个没过,很明显是d的问题没处理好:
我们用另一个思路:
我们把求所有的d的最大公约数实际上就是等差数列的真正公差。
然后套公式:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N];
int n;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int d=0;
for(int i=1;i<n;i++)d=gcd(d,a[i]-a[0]);//0和任何一个数的最大公约数就是那个数本身
if(!d)cout<<n<<endl;//d为0,说明是1 1 1 1这种情况,那么给几个数就输出几
else cout<<(a[n-1]-a[0])/d+1<<endl;//否则就套公式
return 0;
}
算术基本定理,这道题用到的公式是:
比如: