posts - 25,  comments - 0,  trackbacks - 0
/*
*/
#include <iostream>
using namespace std;

/*
注意到对于gcd(a,b) = d 我们对(a, b)用欧几里德辗转相除会最终得到
(d, 0)此时对于把a =d, b = 0 带入a*x + b*y = d,显然x = 1,y可以为任意值,
这里y可以为任意值就意味着解会有无数个。我们可以用a = d, b = 0的情况逆推出来
任何gcd(a, b) = d 满足a*x + b*y = d的解。如果x0, y0是b*x + (a%b)*y = d 的解,
那么对于a*x + b*y = d的解呢?
b*x0 + (a%b)*y0 = d => b*x0 + (a - [a/b]*b)*y0 = a*y0 + b*(x0 - [a/b]*y0),
所以a*x + b*y = d的解x1 = y0, y1 = x0 - [a/b]*y0; 这样我们可以程序迭带了。
*/
int extEuclid(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int d = extEuclid(b, a % b, x, y);
    int iTemp = x;
    x = y;
    y = iTemp - (a / b)* y;
    return d;
}
//解同余方程ax = b(mod n) (返回最小的正数x)

int modularLinearEquation(int a, int b, int n)
{
    //等价于求ax + cn = b;
    
//先求a*x1 + c1*n = gcd(a, n)
    int x, y, d;
    d = extEuclid(a, n, x, y);
    if (b % d != 0)
       return -1;
    x = x * (b / d);
    x = (( x % n) + n) % n;
    return x;
}

//中国剩余定理,推导都是数学
int solModularEquations(int b[], int m[], int k)
{

    int iTemp;
    int y;
    int result;

    int M = 1;
    for (int i = 0; i < k; i++)
      M *= m[i];

    result = 0;
    for (int i = 0; i < k; i++)
    {
      iTemp = M / m[i];
      y = modularLinearEquation(iTemp, 1, m[i]);
      result = (result + b[i] * iTemp * y) % M;
    }
    return result;
}

int main()
{
    int x, y , d;
    d = extEuclid(1001, 767, x, y);
    cout << x << endl;
    cout << y << endl;
    cout << d << endl;
    cout << "1001 * x + 767 * y = " << (1001 * x + 767 * y) << endl;
    cout << modularLinearEquation(3, 2, 100) << endl;
    return 0;
}
posted on 2012-06-02 14:31 nk_ysg 阅读(447) 评论(0)  编辑 收藏 引用 所属分类: 算法

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理