常规解法(AC):
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int PCYCLES = 23; const int ECYCLES = 28; const int ICYCLES = 33; const int LCM = PCYCLES*ECYCLES*ICYCLES;//最小公倍数 int nextPeak(int p,int e,int i,int d) { int k = max<int>(max<int>(p,e),i) + 1; for(;;k++) { if((k-p)%PCYCLES == 0 && (k-e)%ECYCLES == 0 && (k-i)%ICYCLES == 0) break; } k %= LCM;//防止k大于最小公倍数LCM if(k <= d) k += LCM;//防止返回负值 return k - d; } int main() { int physical,emotional,intellectual,d; freopen("in.txt","r",stdin); int count = 1; cin>>physical>>emotional>>intellectual>>d; while(physical != -1 && emotional != -1 && intellectual != -1 && d != -1) { cout<<"Case "<<count++<<": the next triple peak occurs in "<<nextPeak(physical,emotional,intellectual,d)<<" days."<<endl; cin>>physical>>emotional>>intellectual>>d; } return 1; }测试数据:
365 365 365 265
0 0 0 0
0 0 0 100
5 20 34 325
4 5 6 7
283 102 23 320
203 301 203 40
-1 -1 -1 -1
使用“中国剩余定理”求解(AC)
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int PCYCLES = 23; const int ECYCLES = 28; const int ICYCLES = 33; int nextPeak(int p,int e,int i,int d) { int n; n = (5544*p+14421*e+1288*i-d+21252)%21252; if(n==0)n=21252; return n; } int main() { int physical,emotional,intellectual,d; freopen("in.txt","r",stdin); int count = 1; cin>>physical>>emotional>>intellectual>>d; while(physical != -1 && emotional != -1 && intellectual != -1 && d != -1) { cout<<"Case "<<count++<<": the next triple peak occurs in "<<nextPeak(physical,emotional,intellectual,d)<<" days."<<endl; cin>>physical>>emotional>>intellectual>>d; } return 1; }
“中国剩余定理”简介、算理及其应用
我国古代数学名著《孙子算经》中,记载这样一个问题: “今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何。”用现在的话来说就是:“有一批物品,3个3个地数余2个,5个5个地数余3个,7个7个地数余2个,问这批物品最少有多少个?”这个问题的解题思路,被称为“孙子问题”、“鬼谷算”、“隔墙算”、“韩信点兵”等等。那么,这个问题怎呢?明朝数学家程大位把这一解法编成四句歌诀:
三人同行七十(70)稀,
歌诀中每一句话都是一步解法:第一句指除以3的余数用70去乘;第二句指除以5的余数用21去乘;第三句指除以7的余数用15去乘;第四句指上面乘得的三个积相加的和如超过105,就减去105的倍数,就得到答案了。即:
70×2+21×3+15×2-105×2=23 《孙子算经》的“物不知数”题虽然开创了一次同余式研究的先河,但由于题目比较简单,甚至用试猜的方法也能求得,所以尚没有上升到一套完整的计算程序和理论的高度。真正从完整的计算程序和理论上解决这个问题的,是南宋时期的数学家秦九韶。秦九韶于公元1247年写成的《数书九章》一书中提出了一个数学方法“大衍求一术”,系统地论述了一次同余式组解法的基本原理和一般程序。
|
根据以上基本原理,则对于pku acm 1006这道题,相当于读入p,e,i,d 4个整数,已知(n+d)%23=p%23; (n+d)%28=e%28; (n+d)%33=i%33,求n 。
解法如下:
使33×28被23除余1,用33×28×8=5544;
使23×33被28除余1,用23×33×19=14421;
使23×28被33除余1,用23×28×2=1288。
(5544×p+14421×e+1288×i)%(23×28×33)=n+d
n=(5544×p+14421×e+1288×i - d)%(23×28×33)