POJ-1006
手痒了用java A了这题。
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int count = 0; int p = in.nextInt(); int e = in.nextInt(); int i = in.nextInt(); int d = in.nextInt(); while (p != -1 || e != -1 || i != -1 || d != -1) { count++; int temp; int xx = -( p / 23 ); for (int x=xx; (temp=x*23+p)-d <= 21252; x++) { if (temp <= d) continue; if ((temp - e) % 28 == 0 && (temp - i) % 33 == 0) { System.out.println("Case "+count+": the next triple peak occurs in "+ (temp-d)+" days."); break; } } p = in.nextInt(); e = in.nextInt(); i = in.nextInt(); d = in.nextInt(); } in.close(); } }
最正确的做法是剩余定理。
中国剩余定理介绍
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,该问题的一般解法国际上称为“中国剩余定理”。具体解法分三步:
- 找出三个数:从3和5的公倍数中找出被7除余1的最小数15,从3和7的公倍数中找出被5除余1 的最小数21,最后从5和7的公倍数中找出除3余1的最小数70。
- 用15乘以2(2为最终结果除以7的余数),用21乘以3(3为最终结果除以5的余数),同理,用70乘以2(2为最终结果除以3的余数),然后把三个乘积相加(15*2+21*3+70*2)得到和233。
- 用233除以3,5,7三个数的最小公倍数105,得到余数23,即233%105=23。这个余数23就是符合条件的最小数。
就这么简单。
用到这题,就是读入p,e,i,d四个数,
已知(n+d)%23=p, (n+d)%28=e, (n+d)%33=i, 求最小的n。
1.使23*28*a%33=1,得a=2,23*28*2=1288
2.使28*33*b%23=1,得b=6,28*33*6=5544
3.使23*33*c%28=1,得c=19,23*33*19=14421
而23,28,33互质,lcm(23,28,33)=21252
最后n=(1288*i+5544*p+14421*e-d)%21252
考虑到n的非负性,n=(n+21252)%21252
这样就完美解决了这题。代码就不写了。