1. 程式人生 > >歐幾裏得算法用法總結

歐幾裏得算法用法總結

pid 整數 變量 b- bsp can 又是 eof com

當年沒填起來的坑,遲早會再一次掉進去!!!想想還是將現在自己會用了的部分記錄下來,以後再做補充。

歐幾裏得算法:

到目前為止也只是用來求一下兩個整數的最大公約數(感覺又是一個巨大無比的坑)。暫時先把這個用法記下來吧。

//非遞歸實現
long long gcd(long long a,long long b)
{
    int temp;
    while(b)
    {
        a = a % b;
        swap(a ,b);
    }
    return a;
}
//遞歸實現
long long gcd(long long a, long long
b) { return b == 0 ? a : gcd(b, a % b); }

擴展歐幾裏得算法:

同樣為自己挖了一個巨大無比的坑,需要自己慢慢去填滿;上代碼吧還是;

//遞歸實現
long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if( b == 0)
    {
        x = 1;
        y = 0;
        return a;//最後的返回值就是a和b的最大公約數
    }

    long long r = exgcd(b,a%b,y,x);
    y
=y-a/b*x;//通過引用同時求出了線性方程的一組特殊解 return r; }

把自己學到的細節一點一點列出來吧,可能邏輯性會差很多;

  1. 首先就是變量的類型,防止變量大小溢出;
  2. 求出的最後的x可能是負的,如果題目要求是正的可以這樣處理。令技術分享圖片, 然後 x = (*x % r + r) % r,註意如果還要求 y 的大小的話,一定要通過等式轉換來重新求出y來才行;

如果是求得技術分享圖片的 x 和 y 的解,一定要對等式左右兩邊同時除以c,即技術分享圖片,然後通過擴展歐幾裏得求得的 x0 = x / c;

附一個擴展歐幾裏得的模板題(因為自己剛剛學的擴展歐幾裏得算法,不太透徹,這個題卡了好久,太渣了。。。。。。)

Romantic HDU2669

技術分享圖片
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#define INF 0x3f3f3f3f

using namespace std;

typedef long long LL;

LL x, y;

LL exgcd(LL a, LL b, LL&x, LL &y)
{
    LL d;
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
        d = exgcd(b, a % b, y, x);
    y -= x * (a / b);
    return d;
}


int main()
{
    LL a,b;
    while(scanf("%lld%lld",&a,&b) != EOF)
    {
        if(exgcd(a,b,x,y) != 1)printf("sorry\n");
        else
        {
            x =  (x % b + b) % b;
            y = (1 - a * x) / b;//就是這裏卡的我一楞一楞的......
            printf("%lld %lld\n",x, y);
        }
    }
    return 0;
}
View Code

歐幾裏得算法用法總結