博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2891 Strange Way to Express Integers ★ (扩展欧几里德解同余式组)
阅读量:5250 次
发布时间:2019-06-14

本文共 2378 字,大约阅读时间需要 7 分钟。

题目链接
题目大意: 很好的一道题,解同余式组: x = r1 (mod m1) x = r2 (mod m2) …… x = rp (mod mp)  
思路: 因为m1, m2, m3, …… , mp不一定两两互素,所以不能直接用中国剩余定理. 不过,我们可以借用中国剩余定理的思想来解决这道题. 我们一个方程一个方程看, 先看第一个方程x = r1 (mod m1), 则最小的解为r1,满足方程的所有解为:x = r1 + k*m1. 我们现在再加第二个方程:x = r2 (mod m2), 根据上面的解可以变形一下方程:r1 + k*m1 = r2 (mod m2)  -> k * m1 = r2 - r1 (mod m2). 则可以根据扩展欧几里德算法求出k(
形如Ax = B (mod C)的同余方程可由扩展欧几里德算法求出,因为它可以转化成ax + by = c的形式~~) 则满足前两个方程的解x就等于r1 + k * m1. 推广一下,如果我们知道了联立前p个方程的解Xp,那么加下一个方程时就可以变为Xp + k * lcm(m1, m2, …… , mp) = r(p+1) (mod m(p+1)),我们依旧可以用扩展欧几里德来求出k,借此求出联立前p+1个方程的解,直到联立完所有解. 无解的判断:当某个方程Xp + k * lcm(m1, m2, …… , mp) = r(p+1) (mod m(p+1))无解时,则整个方程组无解.  
/*①整个过程求解同于方程组x = a1 (mod m1)x = a2 (mod m2)……x = ar (mod mr)(m1 m2 …… mr不必互素, (互素直接用中国剩余定理即可) )②函数indeterminate_equation()求解不定方程ax + by = c  ->  AX = C (mod B)*/#include #include using namespace std;void ext_gcd(long long a, long long b, long long &x, long long &y){    if (b == 0){        x = 1;        y = 0;        return ;    }    ext_gcd(b, a%b, x, y);    long long tmp = x;    x = y;    y = tmp - a/b * y;    return ;}long long gcd(long long a, long long b){    return b ? gcd(b, a % b) : a;}long long lcm(long long a, long long b){    return a / gcd(a, b) * b;}//求解不定方程ax + by = c  ->  AX = C (mod B)bool indeterminate_equation(long long a, long long b, long long c, long long &x, long long &y){    int g = gcd(a, b);    if (c % g != 0){        return false;    }    a /= g;    b /= g;    c /= g;    ext_gcd(a, b, x, y);    x *= c;    y *= c;    //上面过程是求解出x ,y, 下面过程是求x的最小整数值    long long tmp = abs(double(b));    x = (x % tmp + tmp) % tmp;    return true;}long long m[1010];long long r[1010];int main(){    int k;    while(cin >> k){        long long mlcm = 1;        int ok = 1;        for (int i = 1; i <= k; i ++){            cin >> m[i] >> r[i];        }        long long ans = r[1];        for (int i = 2; i <= k; i ++){            long long a = mlcm = lcm(mlcm, m[i-1]);            long long b = m[i];            long long c = r[i] - ans;            long long x, y;            if (indeterminate_equation(a, b, c, x, y)){                ans = ans + x * mlcm;            }            else{                cout << -1 << endl;                ok = 0;                break;            }        }        if (ok)            cout << ans << endl;    }    return 0;}
 

转载于:https://www.cnblogs.com/AbandonZHANG/archive/2013/01/06/4114194.html

你可能感兴趣的文章
Python 装饰器
查看>>
c# 文件笔记
查看>>
Vue 自定义指令
查看>>
帆软 控件内容 清除
查看>>
第一页 - 工具的使用(webstorm)
查看>>
.net static 变量
查看>>
The Number of set-hdu-3006
查看>>
[设计模式]适配器模式与外观模式
查看>>
自定义分页控件,修改自AspNetForums.Controls.Pager
查看>>
ssh 免签登录 亲测可以
查看>>
Linux 进程资源用量监控和按用户设置进程限制
查看>>
IE浏览器整页截屏程序(二)
查看>>
IOS小技巧积累
查看>>
web页面设计稿的完美还原
查看>>
D3.js 之 d3-shap 简介(转)
查看>>
制作满天星空
查看>>
MyBatis日记(三):戏说MyBatis配置文件
查看>>
$_POST和$GLOBALS['HTTP_RAW_POST_DATA'] 的区别
查看>>
类和结构
查看>>
遍历文件夹下所有dll的类
查看>>