求解ax + by = c 这类方程

  基础知识:

  1.对于任意的ax+by=c, 如果我们知道有一组解x0, y0; 那么 x1 = x0+kb'(b'=b/gcd(a,b)), y1 = y0-ka'(a'=a/gcd(a,b));

  求解ax + by = c 的过程如下:

  1.首先我们利用Egcd求出ax+by=g(g = gcd(a,b))的解。 利用此算法我们可以求出三个数g, x, y

  2.然后我们判断c%g==0? 如果不等于0, 那么此方程无整数解。如果等于0的时候那么执行第三步

  3.利用g, x, y, c我们求出ax+by=c的一组解x0 = x*c/g, y0 = y*c/g;

  4.现在我们利用基础知识1可以求解出ax+by=c的任意一组解。当求最小的满足条件的x的时候我们可以利用模运算:

  实例: POJ1061

  题意是有两只青蛙在赤道上跳, 第一只青蛙的起点是x, 每次跳m米, 第二只从y开始每次跳n米, 赤道长度为l, 问两只青蛙最少几步相遇?

  我们可以列出如下方程x+km = y+kn mod(l) => k(m-n) + k1*l = y-x, 代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;
typedef long long LL;

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

int main()
{
    LL x, y, m, n, l;
    cin>>x>>y>>m>>n>>l;
    LL a=m-n, b=l, c=y-x;
    LL g;
    gcd(a, b, g, x, y);
    if(c%g != 0)
    {
        cout<<"Impossible"<<endl;
        return 0;
    }
    LL x0 = c/g*x;
    //x1 = x0+k*b/g
    LL bg = b/g>0?b/g:-b/g;
    x0 = (x0%bg+bg)%bg;           //这里使用模运算求解最小值
    cout<<x0<<endl;
    return 0;
}

 

    

posted @ 2016-02-14 22:53  xing-xing  阅读(6664)  评论(0编辑  收藏  举报