POJ1006

手痒了用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),问物几何?”这个问题称为“孙子问题”,该问题的一般解法国际上称为“中国剩余定理”。具体解法分三步:

  1. 找出三个数:从3和5的公倍数中找出被7除余1的最小数15,从3和7的公倍数中找出被5除余1 的最小数21,最后从5和7的公倍数中找出除3余1的最小数70。
  2. 用15乘以2(2为最终结果除以7的余数),用21乘以3(3为最终结果除以5的余数),同理,用70乘以2(2为最终结果除以3的余数),然后把三个乘积相加(15*2+21*3+70*2)得到和233。
  3. 用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

这样就完美解决了这题。代码就不写了。

原文地址:https://www.cnblogs.com/ay27/p/2923807.html