POJ 1061 不定方程

POJ 1061

题目链接:

题意:

Ax出发,每次走m步;By出发,每次走n步,两人走的总步数需要余L。问至少走多少步才能相遇,不能相遇则输出Impossible

思路:

解不定方程版题。

不定方程,即ax + by = cabc为常数,xy为变量。求其中整数解。

定理:ax + by = c’的所有c’中,得到最小的c’是gcd(a,b),详见算法导论。

故求解方案有之,即根据ax + by = gcd(a,b)得出x0y0。 假设c % gcd(a,b) == 0,则有答案x = x0 * (c / gcd(a,b))y = y0 * (c / gcd(a,b))

需要注意原始ab的正负问题,根据题目具体分析。

源码:

#include <cstdio>

#include <cmath>

#include <cstring>

#include <cstdlib>

#include <string>

#include <algorithm>

#include <iostream>

using namespace std;

#define gcd(a,b) __gcd(a,b)

#define LL long long

LL exceed_gcd(LL a, LL b, LL &x, LL &y)

{

    if(b == 0){

        x = 1;

        y = 0;

        return a;

    }

    LL d = exceed_gcd(b, a%b, x, y);

    LL tx = y, ty = x - a / b * y;  ///关键部分,不能把y前置为a*y/b

//    printf("tx = %I64d, ty = %I64d, a = %I64d, b = %I64d\n", tx, ty, a, b);

    x = tx, y = ty;

    return d;

}

int main()

{

    LL t1, t2, t3, n, m, L;

    while(scanf("%I64d%I64d%I64d%I64d%I64d", &t1, &t2, &m, &n, &L) != EOF){

        LL a, b, x, y;

        a = n - m;

        b = L;

        t3 = t1 - t2;

        if(a < 0){

            a = -a;

            t3 = -t3;

        }

        while(t3 < 0)

            t3 += L;

        t3 %= L;

        LL d = exceed_gcd(a, b, x, y);

        if(t3 % d == 0){

            LL ans = x * (t3 / d) % (b / d);

            if(ans < 0)

                ans += b / d;

            printf("%I64d\n", ans);

        }

        else{

            printf("Impossible\n");

        }

    }

    return 0;

}

修改版

#include <cstdio>

#include <cmath>

#include <cstring>

#include <cstdlib>

#include <string>

#include <algorithm>

#include <iostream>

using namespace std;

#define gcd(a,b) __gcd(a,b)

#define LL long long

LL exceed_gcd(LL a, LL b, LL &x, LL &y)

{

    if(a < 0){

        return exceed_gcd(-a, -b, x, y);

    }

    if(b == 0){

        x = 1;

        y = 0;

        return a;

    }

    LL d = exceed_gcd(b, a%b, y, x);

    y -= a / b * x; ///注意此处x不能前置为 x * a / b

    return d;

}

int main()

{

    LL t1, t2, c, n, m, L;

    while(scanf("%I64d%I64d%I64d%I64d%I64d", &t1, &t2, &m, &n, &L) != EOF){

        LL a, b, x, y;

        a = n - m;

        b = L;

        c = t1 - t2;

        LL d = exceed_gcd(a, b, x, y);

        if(c % d == 0){

            LL ans = x * (c / d) % (b / d); ///本题的特殊处理

            if(ans < 0)

                ans += b / d;

            printf("%I64d\n", ans);

        }

        else{

            printf("Impossible\n");

        }

    }

    return 0;

}

 

你可能感兴趣的:(POJ 1061 不定方程)