北大poj- 1006

生理周期

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 133189   Accepted: 42577

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 1234 days.

注意:即使结果是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.

Source

East Central North America 1999

Translator

北京大学程序设计实习2007, Xie Di

分析:

看到这个题目,三个时间互质,好像没有什么快捷方法,就先尝试暴力破解了。

暴力破解写了3次:

设下一次巅峰时刻分别为p+23*j,i+33*m,e+28*k。

1. j++,m++,k++,直到找到三个数字相等的时刻就是全盛时期。测试数据都过了,但是。。。超时了。

2. 题目要求了,时间不能超过21252天,所以,从d+1开始到21252遍历,找到(ans-p)%23==0 && (ans-e)%28==0 && (ans-i)%33==0时候,就是答案了。耗时250ms。

3. 对2做了点小优化,不再是从d+1到21252一个一个遍历,而是改为,从i+33开始以33为步长进行遍历。耗时110ms。

这个题目也可以用“中国剩余定理”,传说中的韩信点兵啊,具体见http://blog.csdn.net/bo_jwolf/article/details/9355937

第一次:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 #define SUCCESS 1
 5 #define FAILURE 0
 6
 7 int p = 0;
 8 int e = 0;
 9 int i = 0;
10 int d = 0;
11
12 int Search(int j, int M, int *inm, int i)
13 {
14     int m = *inm;
15     int result = FAILURE;
16     while(1)
17     {
18         if(p+23*j == i+M*m)
19         {
20             result = SUCCESS;
21             break;
22         }
23         else if(p+23*j > i+M*m)
24             m++;
25         else if(p+23*j < i+M*m)
26         {
27             m = 0;
28             result = FAILURE;
29             break;
30         }
31     }
32     *inm = m;
33     return result;
34 }
35
36 int Match(int *j, int *k, int *m)
37 {
38     while(*j<65534)
39     {
40         if(SUCCESS == Search(*j,33,m,i))
41         {
42             if(SUCCESS == Search(*j,28,k,e))
43                 return SUCCESS;
44         }
45
46         (*j)++;
47     }
48     return FAILURE;
49 }
50
51 int main(void)
52 {
53     int j = 1;
54     int k = 1;
55     int m = 1;
56     int ans = 0;
57     int n = 0;
58     while(4==scanf("%d %d %d %d", &p, &e, &i, &d) && (p!=-1 || e!=-1 || i!=-1 || d!=-1))
59     {
60         getchar();
61         n++;
62         p = p % 23;
63         e = e % 28;
64         i = i % 33;
65
66         Match(&j,&k,&m);
67
68         ans = p+23*j;
69
70         if(ans < d)
71             ans = 21252 + ans - d;
72         else
73             ans = ans -d;
74
75         if(ans%21252 > d)
76             ans %= 21252;
77
78         printf("Case %d: the next triple peak occurs in %d days.\n", n, ans);
79     }
80     return 0;
81 }

第二次:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int p = 0;
 5 int e = 0;
 6 int i = 0;
 7 int d = 0;
 8
 9 int main(void)
10 {
11     int ans = 0;
12     int n = 0;
13     while(4==scanf("%d %d %d %d", &p, &e, &i, &d) && (p!=-1 || e!=-1 || i!=-1 || d!=-1))
14     {
15         getchar();
16         n++;
17         p = p % 23;
18         e = e % 28;
19         i = i % 33;
20
21         for(ans=d+1;;ans++)
22         {
23             if((ans-p)%23==0 && (ans-e)%28==0 && (ans-i)%33==0)
24             {
25                 break;
26             }
27         }
28
29         if(ans < d)
30             ans = 21252 + ans - d;
31         else
32             ans = ans - d;
33
34         if(ans%21252 > d)
35             ans %= 21252;
36
37         printf("Case %d: the next triple peak occurs in %d days.\n", n, ans);
38     }
39     return 0;
40 }

第三次:

 1 #include <stdio.h>
 2
 3 int p = 0;
 4 int e = 0;
 5 int i = 0;
 6 int d = 0;
 7
 8 int main(void)
 9 {
10     int ans = 0;
11     int n = 0;
12     int flag = 0;
13     while(4==scanf("%d %d %d %d", &p, &e, &i, &d) && (p!=-1 || e!=-1 || i!=-1 || d!=-1))
14     {
15         getchar();
16         p = p % 23;
17         e = e % 28;
18         i = i % 33;
19         ans = i+33;
20         flag = 1;
21
22         if(p==e && e==i && p>d)
23         {
24             ans=p-d;
25             flag=0;
26         }
27         if(p==e && e==i && p<=d)
28         {
29             ans=p+21252-d;
30             flag=0;
31         }
32
33         if(flag)
34         {
35             while(((ans-p)%23)!=0||((ans-e)%28)!=0||ans-d<0)
36                 ans+=33;
37             ans -= d;
38         }
39
40         printf("Case %d: the next triple peak occurs in %d days.\n", ++n, ans);
41     }
42     return 0;
43 }

时间: 2024-10-10 07:01:25

北大poj- 1006的相关文章

北大POJ题库使用指南

原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列组合).递推关系.质因数法 6.计算几何 //凸壳.同等安置矩形的并的面积与周长.凸包计算问题 8.模拟 9.数据结构 //并查集.堆.树形结构 10.博弈论 11.CD有正气法题目分类: 1. 排序 1423, 1694, 1723, 1727, 1763, 1788, 1828, 1838, 1

POJ - 1006 Biorhythms (中国剩余定理)

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, respec

poj 1006(剩余定理)

生理周期 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 111426   Accepted: 34702 Description 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维敏捷,精力容易高度集中.因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天.对于每个人,我们想知道

poj 1006:Biorhythms(水题,经典题,中国剩余定理)

Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 110991   Accepted: 34541 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,

POJ 1006 中国剩余定理

[题意]: 给定p,e,i,d,求解 (x + d) % 23 = p (x + d) % 28 = e(x + d) % 33 = i x最小正整数值 [知识点]: 中国剩余定理 [题解]: 典型的 xmodmi = ai模型,其中mi间两两互素.但该题式子较少,也可以直接自己化简带入值. [代码]: 1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #inc

Biorhythms POJ - 1006

Biorhythms POJ - 1006 题意: 求解一元线性同余方程组. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn=1010; 5 int b[maxn],m[maxn]; 6 int n; 7 void exgcd(int a,int b,int &d,int &x,int &y){ 8 if(!b){d=a;x=1;y=0;} 9

PKU POJ 1006 Biorhythms (中国剩余定理)

中国剩余定理 x = ai (mod mi)  ai和mi是一组数,mi两两互质,求x 令Mi = m1*m2*~mk     其中,mi不包含在内. 因为mi两两互质,所以存在x和y, st   Mi*xi + mi*yi = 1 令ei = Mi*xi ,则有: 则e0a0 + e1a1 + e2a2+ - +en-1*an-1是方程一个解 因为n%3=2,n%5=3,n%7=2且3,5,7互质       使5×7被3除余1,用35×2=70:        使3×7被5除余1,用21×1

转载----POJ 1006 中国剩余定理

本文为转载,源地址:   http://blog.csdn.net/dongfengkuayue/article/details/6461298 POJ 1006   Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 78980   Accepted: 23740 Description Some people believe that there are three cycles in a perso

中国剩余定理小结 (互质,非互质) (poj 1006,hdu 3579)

先证明下中国剩余定理 条件: x%m_1=a_1 x%m_2=a_2 ... x%m_n=a_n m_1,m_2,...,m_n两两互质 证明: 设M=m_1*m_2*m_3*...*m_n M_i=M/m_i 因为gcd(M_i,m_i)=1,所以M_ix+m_iy=1 (t_i*M_i)%m_i=1 //由Ext_gcd(M_i,m_i,x,y)求出,t_i=x 方程组的解:x=a_1*t_1*M_1+...+a_n*t_n*M_n 题目:poj 1006 http://poj.org/pr

生理周期,POJ(1006)

题目链接:http://poj.org/problem?id=1006 解题报告: 1.枚举天数的时候可以根据前面的结果直接跳过一些错误的答案. ///三个周期是23,28,33, #include <stdio.h> int main() { int p,e,i,d,Case=1; while(scanf("%d%d%d%d",&p,&e,&i,&d),p!=-1) { int t1=p%23,t2=e%28,t3=i%33;///三个周期