POJ1006
求满足同余方程组 x % 23 = p, x % 28 = e, x % 33 = i 的最小的x的值,答案最大不会超过21252(23*28*33)
直接枚举答案就好了,数据太水,正解应该是中国剩余定理
枚举:
#include<cstdio>
using namespace std;
int main(){
for (int phy,emo,itl,day,cnt=0; ; ){
scanf("%d%d%d%d", &phy, &emo, &itl, &day); ++cnt;
if (phy==-1) break;
phy%=23; emo%=28; itl%=33;
for (int i=1; i<=21252; ++i){
if (((i+day)%23==phy) && ((i+day)%28==emo) && ((i+day)%33==itl)){
printf("Case %d: the next triple peak occurs in %d days.\n", cnt, i);
break;
}
}
}
}
-------------------------------------------------------------------明天补充中国剩余定理------------------------------------------------
中国剩余定理:设m1,m2...mk是k个两两互素的正整数,m = m1*m2*...*mk,Mi = m / mi,1 <= i <= k
那么同余方程组 x≡bi ( mod mi ) 有惟一解 x ≡ b1*M1*M1'+b2*M2*M2'+...+bk*Mk*Mk'
其中Mi‘是Mi对于mi的逆元,即Mi*Mi'≡1 ( mod mi )
证明:对任意1 <= i , j <= k,i ≠ j 时,(mi,mj) =1,所以(Mi,mi)=1,那么存在Mi的逆元Mi',此时mj|Mi,所以对每个j满足
b1*M1*M1'+b2*M2*M2'+...+bk*Mk*Mk' ≡ bjMjMj' ≡ bj ( mod mj )
则 x ≡ b1*M1*M1'+b2*M2*M2'+...+bk*Mk*Mk'为同余方程组的解
解的惟一性在此不做证明了
#include<cstdio>
using namespace std;
int phy,emo,itl,day;
void ExGcd(int a,int b,int &x,int &y){
if (!b){
x=1; y=0;
return;
}
ExGcd(b,a%b,x,y);
int tmp=x; x=y; y=tmp-a/b*y;
}
int CRT(){
int M[4]={0,28*33,23*33,23*28};
int x,y,ans=0;
ExGcd(M[1],23,x,y);
ans=(ans+M[1]*x*phy)%21252;
ExGcd(M[2],28,x,y);
ans=(ans+M[2]*x*emo)%21252;
ExGcd(M[3],33,x,y);
ans=(ans+M[3]*x*itl)%21252;
if (ans<0) ans+=21252;
return ans;
}
int main(){
for (int cnt=0; ; ){
scanf("%d%d%d%d", &phy, &emo, &itl, &day); ++cnt;
if (phy==-1) break;
int ans=CRT()%21252;
if (ans<=day) ans+=21252;
printf("Case %d: the next triple peak occurs in %d days.\n", cnt, ans-day);
}
return 0;
}

浙公网安备 33010602011771号