POJ 1006 Biorhythms(中国剩余定理)

来源:互联网 发布:淘宝质量好的女鞋店 编辑:程序博客网 时间:2024/05/17 23:05

题目链接:http://poj.org/problem?id=1006

题       意:给你p,e,i三个事件的发生时间及他们的周期(23,28,33),求他们同时发生的时间。

思       路:他们同时发生即满足有x:x%23==p&&x%28==e&&x%33==i而x==num+d(num即为所求)。

                  这是怎么来的呢?

                  首先我们要知道,任意两个峰值之间一定相距整数倍的周期。假设一年的第N天达到峰值,则下次达到峰值的时间为N+Tk(T是周期,k是任意正整数)。所以,三个峰值同时出现的那一天(S)应满足

                             S = N1 + T1*k1 = N2 + T2*k2 = N3 + T3*k3

                  N1,N2,N3分别为为体力,情感,智力出现峰值的日期, T1,T2,T3分别为体力,情感,智力周期。 我们需要求出k1,k2,k3三个非负整数使上面的等式成立。

                   想直接求出k1,k2,k3貌似很难,但是我们的目的是求出S, 可以考虑从结果逆推。根据上面的等式,S满足三个要求:除以T1余数为N1,除以T2余数为N2,除以T3余数为N3。这样我们就把问题转化为求一个最小数,该数除以T1余N1,除以T2余N2,除以T3余N3。这就是著名的中国剩余定理,我们的老祖宗在几千年前已经对这个问题想出了一个精妙的解法。依据此解法的算法,时间复杂度可达到O(1)。这就涉及到所谓的 “中国剩余定理 ”。

                 此部分为转载:/*****************************************************************************************************************/

                 《孙子算经》中有“物不知数”问题:“今有物不知其数,三三数之余二 ,五五数之余三 ,七七数之余二,问物几何?”答为“23”。

                                  --------这个就是传说中的“中国剩余定理”。 其实题目的意思就是,n % 3 = 2, n % 5 = 3, n % 7 = 2; 问n是多少?

                 那么他是怎么解决的呢?

                 题目中涉及 3, 5,7三个互质的数、

                       令:5 * 7 * a % 3 = 1;  --------------> a = 2; 即5 * 7 * 2 = 70;

                              3 * 7 * b % 5 = 1;  --------------> b = 1; 即3 * 7 * 1 = 21;

                               3 * 5 * c % 7 = 1;  --------------> c  = 1; 即3 * 5 * 1 = 15;

                      为什么要使余数为1:是为了要求余数2的话,只要乘以2就可以,要求余数为3的话,只要乘以3就可以!

                                                            ( 因为题目想要n % 3 =2, n % 5 =3, n % 7 =2; )

                    那么:要使得n % 3 = 2,那么( 5 * 7 * 2 )*2  % 3 = 2;( 因为5 * 7 * 2 % 3 = 1 )

                    同理: 要使得n % 5 = 3,那么( 3 * 7 * 1 )*3  % 5 = 3;( 因为3 * 7 * 1 % 5 = 1 )

                    同理:要使得n % 7 = 2,那么( 3 * 5 * 1 )* 2  % 7 = 2;( 因为3 * 5 * 1 % 7 = 1 )

                   那么现在将( 5 * 7 * 2 )* 2和( 3 * 7 * 1 )* 3和(  3 * 5 * 1 )* 2相加会怎么样呢?我们知道

                (  5 * 7 * 2 )* 2可以被5和7整除,但是%3等于2

                (  3 * 7 * 1 )* 3可以被3和7整除,但是%5等于3

               (  3 * 5 * 1 )* 2可以被3和5整除,但是%7等于2

                 那么即使相加后,%3,  5, 7的情况也还是一样的!

那么就得到一个我们暂时需要的数( 5 * 7 * 2 )* 2 +( 3 * 7 * 1 )* 3 +( 3 * 5 * 1 )* 2 = 233。

但不是最小的!所有我们还要 233 % ( 3 * 5 * 7 ) == 23  得解!

             /*************************************************************************************************************************/

例如此题:

现在看看此题:x % 23 == p; x % 28 == e; x % 33 == i;求x

按照以上算法: 

                 使 33 * 28 * a % 23 = 1,得a = 6; 33 * 28 * 6 = 5544; 

                使23 * 33 * b % 28 = 1, 得b = 19;23 * 33 * 19 = 14421; 
                使23 * 28 * c % 33 = 1, 得c = 2;  23 * 28 * 2 = 1288。 

                那么x  =  5544 * p + 14421 * e + 1288 * i)%(LCM(23,28,33))

                那么x-d即相差的时间天数!

               因为有范围限制,所以为了保证数据的准确性,那么(x-d) %= 21252;且如果此时<=0,那么(x-d)  += 21252  。

 

 代码如下:

<span style="font-size:12px;">#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>using namespace std;int main(){    int d, p, e, i, t = 1;    while ( scanf ( "%d %d %d %d", &p, &e, &i, &d ) != EOF )    {        if( d == -1 && p == -1 && e == -1 && i == -1 ) break;        int sum = 23*28*33;        int ans =( ( 5544*p + 14421*e + 1288*i ) % sum - d ) % 21252 ;        if(ans<=0) ans+=21252;        printf("Case %d: the next triple peak occurs in %d days.\n",t++,ans);    }    return 0;}</span>


 

 

 

 

        

0 0
原创粉丝点击