传说中的“中国剩余定理”
问题描述:###
对于3个互质的自然数:a, b, c
我们需要求一个数x, 使得下列式子全部成立:
-x%a = m1;
-x%b = m2;
-x%c = m3;
求解过程:###
那么令:
k1 = a * b;
k2 = b * c;
k3 = a * b;
再求 t1 和 p1
t1 = k1 * p1, t1 % a = 0 && t1 % b = 0 && t1 % c = 1;
由于 k1 = a * b;
所以 t1 % a = 0 && t1 % b = 0显然成立;
所以我们只需要求一个p1 使得 t1 % c = 1成立
为了使t1 % c = 1
我们通过下列代码实现
int p1 = 1; for( ; p1 < c ; p1 ++){ t1 = k1 * p1; if(t1 % c == 1) break; }
p1 < c是因为我们是求(t1 % c = 1)
这样求出 t1;
类似的
t2 = k2 * p2, t2 % a = 0 && t2 % c = 0 && t2 % b = 1;
t3 = k3 * p3, t3 % b = 0 && t1 % c = 0 && t3 % a = 1;
求出 t2 和 t3;
最后
那么 x = t1 * m3 + t2 * m2 + t3 * m1;
如果 x > a * b * c;
那么 x = x - a * b * c;
证明:###
因为
t1 = k1 * p1, t1 % a = 0 && t1 % b = 0 && t1 % c = 1;
t2 = k2 * p2, t2 % a = 0 && t2 % c = 0 && t2 % b = 1;
t3 = k3 * p3, t3 % b = 0 && t1 % c = 0 && t3 % a = 1;
x = t1 * m3 + t2 * m2 + t3 * m1;
因为
t1 % a = 0 && t1 % b = 0 && t1 % c = 1;
所以
t1 * m3 % a = 0 && t1 * m3 % b = 0 && t1 * m3 % c = m3;
同理:
t2 * m2 % a = 0 && t2 * m2 % c = 0 && t2 * m2 % b = m2;
t3 * m1 % b = 0 && t3 * m1 % c = 0 && t3 * m1 % a = m1;
所以 x =
t1 * m3 + t2 * m2 + t3 * m1
% a: 0 + 0 + m3
% b: 0 +m2 + 0
% c: m1 + 0 + 0
Over~
实现代码:###
代码如下:
其中:genPara是用于生产参数(a, b, c)的
`
package poj;
import java.util.Scanner;
public class Poj1006 {
public static void main(String[] args) {
// genPara();
Scanner sc = new Scanner(System.in);
int c = 0;
while (true) {
c++;
int p = sc.nextInt();
int e = sc.nextInt();
int i = sc.nextInt();
int d = sc.nextInt();
if (p == -1 && e== -1 && i == -1 && d == -1)
break;
int ans = (5544 * p + 14421 * e + 1288 * i-d+21252) % 21252;
if(ans==0)
ans=21252;
System.out.println("Case " + c + ": the next triple peak occurs in " + ans + " days.");
}
sc.close();
}
public static void genPara(){
int m1 = 23;
int m2 = 28;
int m3 = 33;
int a = 1;
int b = 1;
int c =1;
int k1 = m2*m3*a;
int k2 = m1*m3*b;
int k3 = m1*m2*c;
for(; a < 23 ; a ++){
k1 = m2*m3*a;
if(k1%m1 == 1)
break;
}
for(; b < 28 ; b ++){
k2 = m1*m3*b;
if(k2%m2 == 1)
break;
}
for(; c < 33 ; c ++){
k3 = m1*m2*c;
if(k3%m3 == 1)
break;
}
System.out.println("k1:"+k1);
System.out.println("k2:"+k2);
System.out.println("k3:"+k3);
}
}
`