1. 程式人生 > >擴展歐幾裏德 poj1061 青蛙的約會

擴展歐幾裏德 poj1061 青蛙的約會

long using tracking print 返回 imp 有時 pac func

擴展歐幾裏德很經典。可是也有時候挺難用的。一些東西一下子想不明確。。

於是來了一個逆天模板。。僅僅要能列出Ax+By=C。就能解出x>=bound的一組解了~

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

/*能夠得到x>=bound時的x和y,返回true表示有解
否則無解,我僅僅想問這個模板無腦調用有木有~
可是不同的題目特判不同,有的地方記得還是特判,比方a和b的正負和是否為0~*/
bool solve(LL a, LL b, LL c, LL bound, LL &x, LL &y) {
    LL xx, yy, d = exgcd(a, b, xx, yy);
    if(c % d) return false;

    xx = xx * c / d; yy = yy * c / d;
    LL t = (bound - xx) * d / b;

    x = xx + b / d * t;
    if(x < bound) {
        t++;
        x = xx + b / d * t;
    }
    y = yy - a / d * t;
    return true;
}


對於這道題,,我們能得出

A=n-m,B=L,C=x-y

註意A的正負性和是否為0。即可了。然後直接套模板 。以下就是個套模板的樣例

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 3e4 + 5;

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

/*能夠得到x>=bound時的x和y,返回true表示有解
否則無解,我僅僅想問這個模板無腦調用有木有~
可是不同的題目特判不同,有的地方記得還是特判,比方a和b的正負和是否為0~*/
bool solve(LL a, LL b, LL c, LL bound, LL &x, LL &y) {
    LL xx, yy, d = exgcd(a, b, xx, yy);
    if(c % d) return false;

    xx = xx * c / d; yy = yy * c / d;
    LL t = (bound - xx) * d / b;

    x = xx + b / d * t;
    if(x < bound) {
        t++;
        x = xx + b / d * t;
    }
    y = yy - a / d * t;
    return true;
}

int main() {
    LL x, y, m, n, L;
    LL A, B, C, X, Y;
    while(~scanf("%I64d%I64d%I64d%I64d%I64d", &x, &y, &m, &n, &L)) {
        A = n - m; B = L; C = x - y;
        if(A == 0) { //使用solve唯一的特判放在外面
            printf("Impossible\n");
            continue;
        }
        if(A < 0) A = -A, C = -C; //保證A和B都是正數
        if(solve(A, B, C, 0, X, Y)) { //得到的x會>=1,由於不可能是0,並且也必需要非負嘛,理論上0和1都一樣
            printf("%I64d\n", X); //對,,就是這樣,。做完了。
        } else {
            printf("Impossible\n");
        }
    }
    return 0;
}


擴展歐幾裏德 poj1061 青蛙的約會