POJ 1006 同余方程组 -- 扩展欧几里得求逆元

来源:互联网 发布:首次统计网络零售额 编辑:程序博客网 时间:2024/06/05 01:18

传送门:POJ 1006

题意

给定体力,情感,智慧的一个出现日期(周期已知), 以及当前日期, 求最少再过多少天同时出现三个峰值

题解

同余方程组, 设x 是要求的解, 令 y = x + d(当前日期),则
y ≡ p (mod 23), y ≡ i (mod 28), y ≡ e (mod 33);
用中国剩余定理求解, 转载一篇文章:中国剩余定理

AC code:(0ms)

#include<iostream>#include<cstdio>using namespace std;typedef long long LL;int p, i, e, d, x, y;int m[4] = { 0, 23, 28, 33 };int a[4];void expgcd(int a, int b, int &x, int &y) {    if (!b) {        x = 1;        y = 0;        return;    }    expgcd(b, a % b, y, x);    y -= a / b * x;}int main() {    //freopen("in.txt", "r", stdin);    int M = 1;    for (int i = 1; i <= 3; ++i) {        M *= m[i];    }    int kase = 1;    while (cin >> a[1] >> a[2] >> a[3] >> d) {        if (~d) {            int res = 0;            for (int i = 1; i <= 3; ++i) {                expgcd(M / m[i], m[i], x, y);//扩展欧几里得求逆元                res = (res + a[i] * x * M / m[i]) % M;//累加res并在M下取模            }            if (res <= 0) res += M;//非整数处理            while (res <= d) {                res += M;//>d处理            }            cout << "Case " << kase++ << ": the next triple peak occurs in ";            cout << res - d << " days." << endl;        }        else break;    }    return 0;}
0 0
原创粉丝点击