c641: 滿滿的糖果屋 #2

Tags: c.r.t


出處:https://zerojudge.tw/ShowProblem?problemid=c641
提交:https://zerojudge.tw/Submissions?problemid=c641&account=allllllan123456


問題:給你三組 $x\equiv r_i$ (mod $p_i$),其中 $p_i$ 為相異質數,且 $0\lt r_i\lt p_i\lt 100$,請找出滿足方程組並且大於所有 $p_i$ 的最小正整數 $x_0$。


解法:此乃中國剩餘定理的經典題型,本筆記有專頁解說。惟這題有特別要求 $x_0$ 要大於所有的 $p_i$,第 29 行的答案要特別檢查。


 1#include <bits/stdc++.h>
 2using namespace std;
 3
 4inline int nnm(int i, int n) { // nonnegative modulo
 5    return (i % n + n) % n;
 6}
 7
 8int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); // IO 優化
 9    int r[3], m[3];
10    while (cin >> m[0] >> m[1] >> m[2] >> r[0] >> r[1] >> r[2]) {
11        int maxM = *max_element(m, m+3);
12        // let x = r[0] (mod m[0]) and x = r[1] (mod m[1]),
13        // then m[0] * t + r[0] = r[1] (mod m[1])
14        //  ==> m[0] * t + m[1] * k = r[1] - r[0] (mod m[1]).
15        // Suppose m[0] * t0 + m[1] * k0 = 1, then
16        // x == m[0] * t0 * {r[1] - r[0] (mod m[1])} + r[0] (mod m[0]*m[1]).
17        for (int i=0; i+1<3; i++) {
18            int a=m[i], b=m[i+1], x1=1, y1=0, x2=0, y2=1;
19            do {
20                int q = (a*x1 + b*y1) / (a*x2 + b*y2);
21                int x3 = x1 - q*x2;
22                int y3 = y1 - q*y2;
23                x1 = x2; y1 = y2; x2 = x3; y2 = y3;
24            } while (a*x2 + b*y2);
25            x1 = (x1 + b) % b; // x1 is t0 mentioned above.
26            r[i+1] = m[i] * x1 * nnm(r[i+1]-r[i], m[i+1]) + r[i];
27            m[i+1] *= m[i];
28            r[i+1] %= m[i+1];
29        }
30        cout << r[2] + (r[2]<=maxM) * m[2] << '\n';
31    }
32    return 0;
33}

no image