标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 124113 | Accepted: 39154 |
Description
Input
Output
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.
大概意思就是人的体力,情绪和智力的状态分别以23天,28天和33天为周期循环,每个循环中有一天是该指标对应的峰值日。输入p,e,i,d。分别代表第p天体力是峰值,第e天情绪是峰值,第i天智力是峰值,而当前是第d天。让你求多少天之后体力、情绪和智力的峰值日凑到同一天。
这个题目用暴力破解的方法可以解决,但是使用中国剩余定理去解决这种问题无疑是一种更加优雅的方法。
二、中国剩余定理
中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。
按照我的理解,除数是三个质数3、5、7,所以满足这个条件的整数一定是以3*5*7=105为周期循环出现的。我们只需要求出满足条件的一个数,把它除以105得到的余数就是满足条件的最小解。
我们先找到符合第一个条件:除以三余二的数。这里我们为了不让除数5和7惹麻烦,我们就在5和7的公倍数中找:
5和7的最小公倍数:35。35%3=2 好的,我们找到了的第一个数A=35
同理再找第二个数:
3和7的最小公倍数:21。21%5=1 我们要除五余三的数,所以把结果乘上3,(21*3)%5=3 第二个数B=63
再找第三个数:
3和5的最小公倍数:15。15%7=1-------->(15*2)%7=2 C=30
我们看到 A: 除3余2 除5余0 除7余0
B: 除3余0 除5余3 除7余0
C: 除3余0 除5余0 除7余2 我们把这三个数加起来
Σ= D: 除3余2 除5余3 除7余2 =128 是同时满足这三个条件的数!
明显D不是最小满足这个条件的数,把它减去105得到28就是这个问题的解。
三、应用
回到1006题中,以第三行的输入:5 20 34 325为例,X除23余5,除28余20,除33余34(即余1)。可以得到
A:28*33=924 924除23余4,而我们要的是余5的数,怎么办呢?我们把924从1乘到23,肯定能找到余数是5的结果:6468。
同理。B=12144,C=1288
X=A+B+C=19990,减掉325得到19575即为所求。
四、代码
上班的时候用记事本写的,没注释,将就着看吧。
1 #include<stdio.h> 2 3 int p,e,i,p1,e1,i1,t1,t2,t3,t,sum,result,j,count; 4 p=23,e=28,i=33,count=1; 5 6 void cal(int p1,int e1,int i1,int t) 7 { 8 t1=e*i; 9 for(j=0;j<p;j++) 10 { 11 if(t1%p==p1%p) 12 { 13 break; 14 } 15 t1+=e*i; 16 } 17 18 t2=p*i; 19 for(j=0;j<e;j++) 20 { 21 if(t2%e==e1%e) 22 { 23 break; 24 } 25 t2+=p*i; 26 } 27 28 t3=p*e; 29 for(j=0;j<i;j++) 30 { 31 if(t3%i==i1%i) 32 { 33 break; 34 } 35 t3+=p*e; 36 } 37 38 sum=t1+t2+t3; 39 result=sum; 40 41 if(sum<=t) 42 { 43 printf("Case %d: the next triple peak occurs in %d days.\n",count,sum-t); 44 } 45 else 46 { 47 while(sum>t) 48 { 49 sum-=21252; 50 } 51 printf("Case %d: the next triple peak occurs in %d days.\n",count++,sum-t+21252); 52 } 53 } 54 int main() 55 { 56 while(1) 57 { 58 scanf("%d %d %d %d",&p1,&e1,&i1,&t); 59 if(p1==-1) 60 { 61 break; 62 } 63 else 64 { 65 cal(p1,e1,i1,t); 66 } 67 } 68 69 70 return 0; 71 }
标签:
原文地址:http://www.cnblogs.com/Nbox1989/p/5068009.html