POJ1006 中国剩余定理

定义:


若$m_1,m_2,m_3,cdots,m_n$是两两互素的正整数,则同余方程组
$egin{array}{c}
     xequiv a_1( mod\,m_1) \
     xequiv a_2( mod\,m_2) \
     xequiv a_3( mod\,m_3) \
cdotscdotscdotscdots \
     xequiv a_n( mod\,m_n) \
end{array}$
有模$M=m_1m_2m_3cdots m_n$的唯一解,即为中国剩余定理。解为
$xequiv (a_1M_1M_1^{-1}+a_2M_2M_2^{-1}+cdots +a_nM_nM_n^{-1})mod\,M$
其中$M_i=frac{M}{m_i}$,而$M_i^ {-1}$是$M_i$的逆元。


POJ1006 Biorhythms

给你三个周期分别是23,28,33(互质),并且峰值不是一天,给出起始的时间,求出再过最少多少天后三个峰值同时出现。

#include "iostream"
 #include "stdio.h"
 using namespace std;
int s[] = {23,28,33};
 void ext_gcd(int a, int b, int &d, int& x, int& y) {
     if (!b){x = 1; y = 0; d = a;}
     else {
         ext_gcd(b, a%b, d, y, x);
         y -= x*(a/b);
     }
 }
int CRT(int a[],int m[],int n) {
     int M = 1;  
     int ans = 0;  
     for(int i = 0; i < n; i++)  M *= m[i];  
     for(int i = 0; i < n; i++) {  
         int x, y, d;  
         int Mi = M/m[i];  
         ext_gcd(Mi, m[i], d, x, y);  
         ans = (ans + Mi *x*a[i]) % M;  
     }  
     if(ans < 0) ans += M;  
     return ans;  
 }  
int main(int argc, char const *argv[])
 {
     int Kcase = 0;
     int a[5];
     while (scanf("%d%d%d%d", &a[0], &a[1], &a[2], &a[3]) != EOF) {
         if (a[0]==-1&&a[1]==-1&&a[2]==-1&&a[3]==-1) break;
         int ans = CRT(a, s, 3);
         if (ans <=a[3]) ans += 21252;
         printf("Case %d: the next triple peak occurs in %d days.
", ++Kcase, ans - a[3]);
     }
     return 0;
 }

原文地址:https://www.cnblogs.com/cniwoq/p/7265906.html