H Hello Kiki
来源:互联网 发布:电脑按java干什么 编辑:程序博客网 时间:2024/05/07 13:28
H Hello Kiki
Description
One day I was shopping in the supermarket.There was a cashier counting coins seriously when a little kid running andsinging "门前大桥下游过一群鸭,快来快来 数一数,二四六七八". And then the cashier put the counted coins back morosely andcount again...
Hello Kiki is such a lovely girl that sheloves doing counting in a different way. For example, when she is counting Xcoins, she count them N times. Each time she divide the coins into several same sized groups and write down the groupsize Mi and the number of the remaining coins Ai on her note.
One day Kiki's father found her note and hewanted to know how much coins Kiki was counting.
Input
The first line is T indicating the numberof test cases.
Each case contains N on the first line,Mi(1 <= i <= N) on the second line, and corresponding Ai(1 <= i <=N) on the third line.
All numbers in the input and output areintegers.
1 <= T <= 100, 1 <= N <= 6, 1<= Mi <= 50, 0 <= Ai < Mi
Output
For each case output the least positiveinteger X which Kiki was counting in the sample output format. If there is nosolution then output -1.
Sample Input
2
2
14 57
5 56
5
19 54 40 24 80
11 2 36 20 76
Sample Output
Case 1: 341
Case 2: 5996
——写自Jun Chen
这道题目是中国剩余定理的应用,一开始的时候没有注意数据情况,以为是纯中国剩余定理,直接用公式就可以了,谁知道第二组数据居然没有结果输出!后来才发现题目中M[i]之间可以不互素,所以不能直接用公式做!但是在不互素的情况下也不是就一定就无解,也可能存在解的!如果互素的话,那是一定存在解的!
首先以两个同余方程组成的方程组为例:
n = n1 (mod m1) and
n = n2 (mod m2)
有解的前提条件是gcd(m1, m2) | (n2 - n1)
1) 用扩展欧几里德算法计算t * m1 + s * m2 = gcd(m1, m2) = d
2) 计算tt, ss使其满足tt * m1 + ss * m2 = n2 - n1
具体方法是tt = t * (n2 - n1) / d,ss = s * (n2 - n1) / d
3) 那么nn = tt * m1 + n1 = -ss * m2 + n2 (这两个用哪个都行)
4) 我们已经把两个同余方程组变成了一个:
n = nn (mod LCM(m1, m2))
重复这个过程,每次合并两个方程,就可以解决整个方程组了
代码如下:
#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>#include <map>#include <set>using namespace std;int T, N;__int64 M[1005], A[1005];void exgcd(__int64 m, __int64 n, __int64 &d, __int64 &x, __int64 &y) //扩展的欧几里德算法;{ if (n == 0) { d = m, x = 1, y = 0; } else { exgcd(n, m % n, d, y, x);//在刘汝佳的算法入门经典中的方法; y -= x * (m / n); }}__int64 mod(__int64 x, __int64 n){ return (x % n + n) % n; }/*x = a1 (mod m1)x = a2 (mod m2)a1 + m1 * p1 = a2 + m2 * p2a2 - a1 = m1 * p1 - m2 * p2d = gcd(m1, m2) = m1 * q1 + m2 * q2p1 = q1 * (a2 - a1) / dx = a1 + m1 * p1 (mod LCM(m1, m2))*/bool reduce(__int64 a1, __int64 m1, __int64 a2, __int64 m2, __int64 &aa, __int64 &mm){ __int64 d, q1, q2; exgcd(m1, m2, d, q1, q2); if ((a2 - a1) % d == 0) {//存在解的情况; __int64 p1 = q1 * ((a2 - a1) / d); mm = m1 * (m2 / d); aa = mod(a1 + m1 * p1, mm); return true;}return false;}bool check(__int64 X) {for (int i = 0; i < N; ++i)if (X % M[i] != A[i])return false;return true;}int main(){cin >> T;for (int id = 1; id <= T; ++id){cin >> N;for (int i = 0; i < N; ++i)cin >> M[i];for (int i = 0; i < N; ++i) cin >> A[i];__int64 aa, mm;bool ok = true;if (N == 1) {aa = A[0], mm = M[0];} else {ok &= reduce(A[0], M[0], A[1], M[1], aa, mm);for (int i = 2; i < N && ok; ++i)ok &= reduce(A[i], M[i], aa, mm, aa, mm);}if (aa == 0) aa += mm;cout << "Case " << id << ": " << (ok ? aa : -1) << endl;} return 0;}
- H Hello Kiki
- Hdu 3579 Hello Kiki
- hdu 3579 Hello Kiki
- HDU 3579 (Hello Kiki)
- hdu 3579 Hello Kiki
- hdoj-3579-Hello Kiki
- HDU3575 Hello Kiki
- [HDU3579] Hello Kiki
- HDU 3579 Hello Kiki
- hdoj 3579 Hello Kiki 【CRT】
- HDU 3579 Hello Kiki【中国剩余】
- Hello Kiki(hdu3579线性同与方程)
- HDU 3579——Hello Kiki
- HDU3579 Hello Kiki 解同余方程组
- hdu 3579 Hello Kiki 同余
- HDU3579 Hello Kiki(CRT非互质)
- 【HDU】3579 - Hello Kiki(CRT)
- HDOU-----3579---Hello Kiki扩展欧几里得
- thick box
- JQuery版本冲突问题
- spring的一些提醒
- 层级实时记忆脑皮质学习算法(HTM Cortical Learning Algorithms)-------英文原版翻译
- 比較一個文件中的單詞是否在另一個文件中出現?
- H Hello Kiki
- 求职笑话
- C++ Vector 使用心得
- MFC ADO RecordCount 返回值为-1
- VS操作技巧
- 程序员面试100题之十二:求数组中最长递增子序列
- Asp.net 中如何调用母版中的变量和变量
- linux epoll模型
- 创业公司的痛点及药方-认识