1. 程式人生 > >poj 1006 Biorhythms(中國剩餘定理的應用)

poj 1006 Biorhythms(中國剩餘定理的應用)

Biorhythms
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 125633 Accepted: 39673

Description

Some people believe that there are three cycles in a person's life that start the day he or she is born. These three cycles are the physical, emotional, and intellectual cycles, and they have periods of lengths 23, 28, and 33 days, respectively. There is one peak in each period of a cycle. At the peak of a cycle, a person performs at his or her best in the corresponding field (physical, emotional or mental). For example, if it is the mental curve, thought processes will be sharper and concentration will be easier. 
Since the three cycles have different periods, the peaks of the three cycles generally occur at different times. We would like to determine when a triple peak occurs (the peaks of all three cycles occur in the same day) for any person. For each cycle, you will be given the number of days from the beginning of the current year at which one of its peaks (not necessarily the first) occurs. You will also be given a date expressed as the number of days from the beginning of the current year. You task is to determine the number of days from the given date to the next triple peak. The given date is not counted. For example, if the given date is 10 and the next triple peak occurs on day 12, the answer is 2, not 3. If a triple peak occurs on the given date, you should give the number of days to the next occurrence of a triple peak. 

Input

You will be given a number of cases. The input for each case consists of one line of four integers p, e, i, and d. The values p, e, and i are the number of days from the beginning of the current year at which the physical, emotional, and intellectual cycles peak, respectively. The value d is the given date and may be smaller than any of p, e, or i. All values are non-negative and at most 365, and you may assume that a triple peak will occur within 21252 days of the given date. The end of input is indicated by a line in which p = e = i = d = -1.

Output

For each test case, print the case number followed by a message indicating the number of days to the next triple peak, in the form: 

Case 1: the next triple peak occurs in 1234 days. 

Use the plural form ``days'' even if the answer is 1.

Sample Input

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

Sample Output

Case 1: the next triple peak occurs in 21252 days.
Case 2: the next triple peak occurs in 21152 days.
Case 3: the next triple peak occurs in 19575 days.
Case 4: the next triple peak occurs in 16994 days.
Case 5: the next triple peak occurs in 8910 days.
Case 6: the next triple peak occurs in 10789 days.
題目翻譯

Description

人生來就有三個生理週期,分別為體力、感情和智力週期,它們的週期長度為23天、28天和33天。每一個週期中有一天是高峰。在高峰這天,人會在相應的方面表現出色。例如,智力週期的高峰,人會思維敏捷,精力容易高度集中。因為三個週期的周長不同,所以通常三個週期的高峰不會落在同一天。對於每個人,我們想知道何時三個高峰落在同一天。對於每個週期,我們會給出從當前年份的第一天開始,到出現高峰的天數(不一定是第一次高峰出現的時間)。你的任務是給定一個從當年第一天開始數的天數,輸出從給定時間開始(不包括給定時間)下一次三個高峰落在同一天的時間(距給定時間的天數)。例如:給定時間為10,下次出現三個高峰同天的時間是12,則輸出2(注意這裡不是3)。

Input

輸入四個整數:p, e, i和d。 p, e, i分別表示體力、情感和智力高峰出現的時間(時間從當年的第一天開始計算)。d 是給定的時間,可能小於p, e, 或 i。所有給定時間是非負的並且小於365, 所求的時間小於21252。  

當p = e = i = d = -1時,輸入資料結束。

Output

從給定時間起,下一次三個高峰同天的時間(距離給定時間的天數)。  

採用以下格式:  

Case 1: the next triple peak occurs in 1234days.  

注意:即使結果是1天,也使用複數形式“days”。

Sample Input

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

Sample Output

Case 1: the next triple peak occurs in 21252 days.

Case 2: the next triple peak occurs in 21152 days.

Case 3: the next triple peak occurs in 19575 days.

Case 4: the next triple peak occurs in 16994 days.

Case 5: the next triple peak occurs in 8910 days.

Case 6: the next triple peak occurs in 10789 days.

思路:(中國剩餘定理的應用)

AC程式碼如下

#include<iostream>
using namespace std;
int main()
{
	int p,e,i,d,T=1;
	while(cin>>p>>e>>i>>d && p!=-1 && e!=-1 && i!=-1 && d!=-1 )
	{
		int ans=5544*p+14421*e+1288*i;
		ans=(ans-d)%21252;
		if(ans<=0)
			ans+=21252;
		cout<<"Case "<<T++<<": the next triple peak occurs in "<<ans<<" days."<<endl;
	}
	return 0;
}

具體分析如下:(關於程式碼中的5544,14421,1288的解釋)

先分析一個例題:(剩餘定理的經典應用)

《孫子算經》中有“物不知數”問題:“今有物不知其數,三三數之餘二 ,五五數之餘三 ,七七數之餘二,問物幾何?”答為“23”。

( ps:其實題目的意思就是,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;

而a,b,c的值的計算通過拓展歐幾里得演算法得出。

為什麼要使餘數為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  得解!

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

// 以上就是演算法解析,貌似講的不是很清晰,哎,大家見諒咯~

設 num 是下一個相同日子距離開始的天數

p,e,i,d 如題中所設!

那麼就可以得到三個式子:( num + d ) % 23 == p; ( num + d ) % 28 == e; ( num + d ) % 33 == i;

p,e,i,d 是我們輸入的,那麼我們需要求出num即可,為了方便,我們將num+d暫時作為一個整體!令x = num + d;

即:x % 23 == p; x % 28 == e; x % 33 == i;求x

怎麼辦?這就涉及到所謂的 “ 中國剩餘定理  。

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。 

那麼num =  5544 * p + 14421 * e + 1288 * i

那麼num-d即相差的時間天數!

注意:因為有範圍限制,那麼(x-d) %= 21252;且如果此時<=0,那麼(x-d)  += 21252   ,以上都只是為了保證在範圍內而已~