最大公约数 数学

108 阅读2分钟

最大公约数

最大公约数用到一个算法叫欧几里得算法,也叫辗转相除法。

欧几里得算法

求(a,b)的最大公约数可以转化为(a,a%b)的最大公约数

证明:

dadbda+bdax+byd|a , d|b, d|a+b,d|ax+by

译:d能整除a并且d能整除b,d就能整除a+b。并且d就能整除x倍a+b倍y

比如2|4 ,2|6 ,2就可以|(6+4)。

image.png 用代码表示为如下:

#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(),头文件为

1246. 等差数列 - AcWing题库
思想

一。首先排个序,然后开个辅助空间。

二.用等差公式 an=a1+(n1)d an=a1+(n-1)d 推出来所有的数

    #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;
}
过了第一个测试样例:

image.png

但是第二个没过,很明显是d的问题没处理好:

image.png

我们用另一个思路:

我们把求所有的d的最大公约数实际上就是等差数列的真正公差。

然后套公式: count=(ana1)/d+1count=(an-a1)/d+1

    #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;
}

算术基本定理,这道题用到的公式是:
N=p1α.p2α.p3αN= p1^α. p2^α. p3^α……

比如:

12=22.3112=2^2.3^1

36=32.2236=3^2.2^2