CRT中国剩余定理
一、前言
引入题目:三个小朋友刚学数学没多久,由于不会进位,只能准确10以内的数。现在有一群羊,羊主人说数量不超过两百。小A每次数到5以后就又回到1开始数,最后剩了3只羊。小B每次数到7就回到1开始数,最后剩了5只羊。小C每次数到8之后就回到1开始数,最后剩余7只羊。请求出这群羊有多少只
二、分析题目
首先我们可以分析题目条件,
x % 5 == 3,为了建立同余方程我们把BC关联进去得到,因为bc的最小公倍数不会对b 和 c造成余数,只会对a造成余数
(b * c) % 5 == 3,化简得:bc ≡ 3 (mod 5)
也就是说我们需要在bc的公倍数中间找到一个数对5(也就是第一个人最多能数到的数5)求余等于3
根据exgcd证明可知如果bc 和 5互质,那么可利用exgcd得
bcx + 5y = 1得到次方程的一个解,因为余数为3,所以还需要乘以3,
依次把每一个都按照上面的步骤计算求和,最后对三个数的最小公倍数求和即可得到最小解了
代码如下:
1 #include "bits/stdc++.h" 2 using namespace std; 3 int exgcd(int &x,int &y,int a,int b) 4 { 5 if(b == 0){ 6 x = 1,y = 0; 7 return a; 8 } 9 int d = exgcd(y,x,b,a % b); 10 y = y - a/b * x; 11 return d; 12 } 13 int main()//用CRT解决此类问题的前提是要保证互质,当然如果不互质我们也可以采用exCRT求解 14 { 15 int b[10][2] = {{5,3},{7,5},{8,7}}; 16 int m = 1; 17 int sum = 0; 18 for(int i = 0;i <= 2;i++) 19 m *= b[i][0]; 20 int a,p; 21 for(int i = 0;i <= 2;i++){ 22 int M = m / b[i][0]; 23 int x = M; 24 if(exgcd(a,p,x ,b[i][0])!= 1) return 0; 25 sum = sum + a * b[i][1] * M; 26 //逆元*另外两个数的乘积*余数 27 //前提条件是另外两个数的乘积 和 这个数互质,满足exgcd 28 //此时可以求得互质的一组答案,但是我们要求的是余数为k的答案,所以我们应该乘以个k,把三个数的答案都相加即可得到该问题的一组解 29 //此时如果我们要求解最小的解,我们可以对三个数的乘积求余,达到最小解 30 } 31 cout << (sum + m) % m << endl;//防止答案为负数,%m是求解最小解 32 return 0; 33 }
三、总结
数论yyds!
本文来自博客园,作者:{scanner},转载请注明原文链接:{https://home.cnblogs.com/u/scannerkk/}

浙公网安备 33010602011771号