一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K。例如,K % 2 = 1, K % 3 = 2, K % 5 = 3。符合条件的最小的K = 23。
Input
第1行:1个数N表示后面输入的质数及模的数量。(2 <= N <= 10) 第2 - N + 1行,每行2个数P和M,中间用空格分隔,P是质数,M是K % P的结果。(2 <= P <= 100, 0 <= K < P)
Output
输出符合条件的最小的K。数据中所有K均小于10^9。
Input示例
3 2 1 3 2 5 3
Output示例
23
解:
方法一
1 #include <stdio.h> 2 3 typedef struct 4 { 5 int p, m; 6 }str; 7 8 str s[10]; 9 10 int cmp(const void *a, const void *b) 11 { 12 return ((str *)a)->p > ((str *)b)->p ? -1 : 1; 13 } 14 15 int main() 16 { 17 int n; 18 while (scanf_s("%d", &n) != EOF) 19 { 20 long long mult = 1; 21 int ans; 22 for (int i = 0; i < n; i++) 23 { 24 scanf_s("%d%d", &s[i].p, &s[i].m); 25 mult *= s[i].p; 26 } 27 qsort(s, n, sizeof(str), cmp); 28 for (int i = 0, flag = 1; flag && i * s[0].p <= mult; i++) 29 { 30 ans = s[0].p * i + s[0].m; 31 for (int j = 1; ans % s[j].p == s[j].m;j++) 32 { 33 if (j == n - 1) 34 { 35 flag = 0; 36 break; 37 } 38 } 39 } 40 printf("%d\n", ans); 41 42 } 43 }
改进法一后的法二:
1 #include <stdio.h> 2 3 4 int main() 5 { 6 int n; 7 while (scanf_s("%d", &n) != EOF) 8 { 9 int a, b, c, d; 10 scanf_s("%d%d", &a, &b); 11 for (int i = 1,j; i < n; i++) 12 { 13 scanf_s("%d%d", &c, &d); 14 for (j = 0; (a * j + b) % c != d; j++); 15 b = a * j + b; 16 a *= c; 17 } 18 printf("%d\n", b); 19 } 20 }
法三:
中国剩余定理(https://baike.baidu.com/item/孙子定理/2841597?fromtitle=%E4%B8%AD%E5%9B%BD%E5%89%A9%E4%BD%99%E5%AE%9A%E7%90%86&fromid=11200132&fr=aladdin)+ 拓展欧几里得
(注意中国剩余定理必满足使用拓展欧几里得求逆元的条件,即n个不同质数,其中n-1个的乘积必与剩下的1个互质)
1 #include <stdio.h> 2 3 int inv[10], pm[20]; 4 5 void Ex_gcd(int a, int b, int *x, int *y); 6 7 int main() 8 { 9 int t; 10 while (scanf_s("%d", &t) != EOF) 11 { 12 long long M = 1, ans = 0; 13 for (int i = 0; i < t; i++) 14 { 15 scanf_s("%d%d", &pm[i], &pm[i + 10]); 16 M *= pm[i]; 17 } 18 for (int i = 0, temp; i < t; i++) 19 { 20 Ex_gcd(M / pm[i], pm[i], &inv[i], &temp); 21 inv[i] = (inv[i] + pm[i]) % pm[i]; 22 ans = (ans + M / pm[i] * inv[i] * pm[i + 10]) % M; 23 } 24 printf("%d\n", ans); 25 } 26 } 27 28 void Ex_gcd(int a, int b, int *x, int *y) 29 { 30 if (b == 0) 31 { 32 *x = 1; 33 *y = 0; 34 return; 35 } 36 Ex_gcd(b, a%b, x, y); //或者可以这么写 37 int t = *y; //ex_gcd(b, a%b, y, x);
38 *y = *x - a / b * (*y); //*y = *y - (a / b)**x; 39 *x = t; //return; 40 return; 41 }