首页 > 试题广场 >

Biorhythms

[编程题]Biorhythms
  • 热度指数:1869 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
    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.

输入描述:
    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.


输出描述:
    Case: the next triple peak occurs in 1234 days.
    Use the plural form "days'' even if the answer is 1.
示例1

输入

0 0 0 0

输出

Case: the next triple peak occurs in 21252 days.
#include<stdio.h>
int main()
{
    int p,e,i,d,temp=0;
    while(scanf("%d %d %d %d",&p,&e,&i,&d)==4)
    {
        for(temp=1;;temp++)
            if((temp-p)%23==0 && (temp-e)%28==0 && (temp-i)%33==0)    break;    
        printf("Case: the next triple peak occurs in %d days.\n",temp-d);
    }
}
暴力解法
发表于 2018-04-21 22:15:00 回复(0)
//枚举 其实很简单  代码优化过了  
#include<stdio.h>
int main(){
int p,e,i,d,num=0;
while(scanf("%d %d %d %d",&p,&e,&i,&d)!=EOF&&p!=-1){
num++;
int k;
   for( k=d+1;(k-p)%23;++k);
for(;(k-e)%28;k+=23);
for(;(k-i)%33;k+=23*28);
printf("Case %d: the next triple peak occurs in %d days.\n",num,k-d);
}
return 0;
}
发表于 2017-02-15 16:35:39 回复(0)
#include <stdio.h>

void TimeGoesBy(int d[4], int len[4])
{
    if(d[1]<=d[2]&&d[1]<=d[3]) d[1]+=len[1];
    else if(d[2]<=d[1]&&d[2]<=d[3]) d[2]+=len[2];
    else d[3]+=len[3];
}

int main()
{
    int d[4];//分别代表今天日期、1峰日期、2峰日期、3峰日期
    int len[4]={0, 23, 28, 33};
    while(scanf("%d%d%d%d",&d[1],&d[2],&d[3],&d[0])!=EOF)
    {
        for(int i=1; i<=3; i++)
        {
            while(d[i]>d[0]) d[i]-=len[i];
        }
        TimeGoesBy(d, len);
        while(d[1]!=d[2] || d[1]!=d[3]) TimeGoesBy(d, len);
        printf("Case: the next triple peak occurs");
        printf(" in %d days.\n", d[1]-d[0]);
    }
    return 0;
}

发表于 2018-03-10 09:15:09 回复(0)

记录三个峰值的日期,每次循环都选择当前日期最小的一个加上周期,直到三者相等

#include<iostream>
using namespace std;

int main(){
    int p, e, i, d;
    while(cin >> p >> e >> i >> d){
        int ps = p, es = e, is = i;
        while(!(ps == es && ps == is) || ps - d == 0){
            if(ps <= es && ps <= is)
                ps += 23;
            else if(es <= ps && es <= is)
                es += 28;
            else if(is <= ps && is <= es)
                is += 33;
        }
        cout << "Case: the next triple peak occurs in " << ps - d << " days." << endl;
    }
    return 0;
}
发表于 2019-03-14 19:44:35 回复(0)
try:
    while True:
        p,e,i,d = list(map(int,input().split()))
        a = b = c = 0
        if p < e:
            a = 1
        else:
            b = 1
        while not (23*a+p == 28*b+e == 33*c+i):      #谁小就加谁,直到相等
            if 23*a+p == min(23*a+p, 28*b+e, 33*c+i):
                a += 1
            elif 28*b+e == min(23*a+p, 28*b+e, 33*c+i):
                b += 1
            else:
                c += 1
        print('Case: the next triple peak occurs in %d days.' % (28*b+e-d))
except Exception:
    pass
编辑于 2018-10-04 10:24:33 回复(0)
#include<stdio.h>
int main()
{
    int p,e,i,d;
    scanf("%d %d %d %d",&p,&e,&i,&d);
    while(1)
    {
        if((p-e)%28==0&&(p-i)%33==0&&p>d)
            break;
        p+=23;
    }
    printf("Case: the next triple peak occurs in %d days.",p-d); 
}

发表于 2020-04-02 10:21:05 回复(1)
def shizidinli(a, b, c, d):
    for i in range(1, 21253):
        k = d + i
        if (k-a) % 23 == 0 and (k-b) % 28 == 0 and (k-c) % 33 == 0:
            print('Case: the next triple peak occurs in {} days.'.format(i))
            break

# while True:
#     try:

s = list(map(int, input().split()))
shizidinli(s[0], s[1], s[2], s[3])
    # except:
    #     break

发表于 2024-03-21 20:33:23 回复(0)
#include <iostream>
using namespace std;
//p e i分别为三个周期的起始日期
int main(){
    int p, e, i, start;
    while (cin >> p >> e >> i >> start){
        int final = start+1;    //不能是同一天
        //只要不满足三个周期都能整除就循环+1
        while (!((final-p)%23==0 && (final-e)%28==0 && (final-i)%33==0)){
            final++;
        }
        cout << "Case: the next triple peak occurs in " << final-start << " days." <<endl;
    }
}

编辑于 2024-03-10 22:52:17 回复(0)
//代码还是比较简单的,按天数枚举即可,就是英文最后有些读不懂了,还是查的翻译...
#include "stdio.h"

int main(){
    int physical,emotional,intellectual;//分别为记录对应的日期(今年第几天出现)
    int date;//现在是今年第几天
    scanf("%d%d%d%d",&physical,&emotional,&intellectual,&date);
    int nextday = 1;
    bool p_flag,e_flag,i_flag;
    while (true){
        p_flag = false;e_flag = false;i_flag = false;
        if((nextday + date - physical)%23 == 0)
            p_flag = true;
        if((nextday + date - emotional)%28 == 0)
            e_flag = true;
        if((nextday + date - intellectual)%33 == 0)
            i_flag = true;
        if(p_flag && e_flag && i_flag)
            break;
        ++nextday;
    }
    printf("Case: the next triple peak occurs in %d days.",nextday);
}

发表于 2023-03-10 09:43:32 回复(0)
不用枚举整个值域,每次对三个数中的最小值做加法即可
#include <cstdio>
#include <iostream>
using namespace std;

int main() {
    int p, e, i, d;
    while (cin >> p >> e >> i >> d)
    {
        while (!(p == e && p == i && p > d))
        {
            if (p <= e && p <= i)
                p += 23;
            else if (e <= p && e <= i)
                e += 28;
            else
                i += 33;
        }
        printf("Case: the next triple peak occurs in %d days.\n", p - d);
    }
}


发表于 2023-03-03 14:51:04 回复(0)
#include <cstdio>
#include <iostream>
using namespace std;

int arr[3]={23,28,33};

//返回最小天数的序号
int mini(int iarr[]){
    if(iarr[0]<=iarr[1]&&iarr[0]<=iarr[2]){
        return 0;
    }else if(iarr[1]<iarr[0]&&iarr[1]<iarr[2]){
        return 1;
    }else{
        return 2;
    }
}

int main() {
    int iarr[3];int id;
    while(scanf("%d%d%d%d",&iarr[0],&iarr[1],&iarr[2],&id)!=-1){
        //全都相等且比给定天数大才跳出循环
        while(!(iarr[0]==iarr[1]&&iarr[1]==iarr[2]&&iarr[0]>id)){
            //哪个小就加哪个,直到相等
            int i=mini(iarr);
            iarr[i]+=arr[i];
        }

        printf("Case: the next triple peak occurs in %d days.\n",iarr[0]-id);
    }
}

发表于 2023-02-13 15:59:13 回复(0)
#include <iostream>
#include <algorithm>

using namespace std;

int main(){
    int p, e, i, d;
    int pp=23, pe=28, pi=33;
    while(cin>>p>>e>>i>>d){
        int j=max(p, max(e, i)), day=1;
        while(1){
            j++;
            if((j-p)%pp==0&&(j-e)%pe==0&&(j-i)%pi==0&&j>d){
                cout << "Case: the next triple peak occurs in " << j-d << " days." << endl;
                break;
            }
        }
    }
    
    return 0;
}

发表于 2022-02-19 17:55:27 回复(0)
#include <stdio.h>

int main(){
    int p,e,i,d,dd;
    while(scanf("%d %d %d %d",&p,&e,&i,&d)!=EOF){
        for(int j=d+1;j<=21252;j++)
            if((j-p)%23==0&&(j-e)%28==0&&(j-i)%33==0) dd=j;
        printf("Case: the next triple peak occurs in %d days.",dd-d);
    }
}
发表于 2022-01-12 16:48:49 回复(0)
#include<iostream>
using namespace std;

int p,e,i,d;

int main() {
    while (cin >> p >> e >> i >> d) {
        int m = (5544*p+14421*e+1288*i) % 21252;
        if (m <= d) {
            m += 21252;
        }
        cout << "Case: the next triple peak occurs in " << m-d << " days." << endl;
    }
    return 0;
}
孙子定理的解法,可以避开枚举直接得到答案。
发表于 2020-07-02 18:04:55 回复(0)
(cur % N) != p 和 (cur - p) % N != 0 有什么区别?后者可以通过,前者超时。
发表于 2020-02-29 09:54:59 回复(0)
/*采用3个map映射存储所有的可行解,然后直接遍历一个Map,
  判断其余的map是否有与其匹配的元素*/
#include <iostream>
#include <map>
using namespace std;

int cp=23,ce=28,ci=33;
map<int,bool> MapP,MapE,MapI;
int main()
{
    int p,e,i,d;
    while(cin>>p>>e>>i>>d){
        int start = p+cp;//从下一个峰值开始计算
        while(start<=21252){
            MapP[start]=true;
            start+=cp;
        }
        start = e+ce;
        while(start<=21252){
            MapE[start]=true;
            start+=ce;
        }
        start = i+ci;
        while(start<=21252){
            MapI[start]=true;
            start+=ci;
        }
        for(auto it=MapP.begin();it!=MapP.end();it++){
            if(MapE[it->first]&&MapI[it->first]){
                printf("Case: the next triple peak occurs in %d days.\n",it->first-d);
                break;
            }
        }
    }
    return 0;
}

发表于 2019-03-23 20:39:03 回复(0)
#include 
int main(){
    const int a=23,b=28,c=33;
    int p,e,i,d,M,M1,M2,M3,m1,m2,m3,x;
    M = a*b*c;
    M1 = M/a; M2 = M/b; M3 = M/c;
    while(scanf("%d%d%d%d",&p,&e,&i,&d)!=EOF){
        int t1=M1%a,t2=M2%b,t3=M3%c;
        m1=m2=m3=0;
        while(t1*m1%a != 1)  m1++;
        while(t2*m2%b != 1)  m2++;
        while(t3*m3%c != 1)  m3++;
        x = p*M1*m1 + e*M2*m2 + i*M3*m3;
        if(p==e && p==i && i==e)
            printf("Case: the next triple peak occurs in %d days.",d<=p?(p-d):M-(d-p));
        else
            printf("Case: the next triple peak occurs in %d days.",(x-d)%M);//求出最近的符合条件的天数
    }
    return 0;
}
编辑于 2018-01-21 22:49:17 回复(1)
啥头像
用暴力方法写了个,等待高手写个高效版

#!/usr/bin/python
#-*- coding:utf-8 -*-

def triplePeak(p, e, i, d):
    maxLimit = (d+21252)
    flag = [0]*(maxLimit+1)
    rlt = maxLimit
    p = p%23 if p%23 else 23; e = e%28 if e%28 else 28; i = i%33 if i%33 else 33
    while p <= maxLimit:
        flag[p] += 1
        p += 23
    while e <= maxLimit:
        flag[e] += 1
        e += 28
    while i <= maxLimit:
        if flag[i]==2 and i>d:
            rlt = i
            break
        i += 33
    return (rlt-d)

idx = 1
while True:
    try:
        p, e, i, d = map(int, raw_input().strip().split())
        if p==-1 and e==-1 and i==-1 and d==-1:
            break
        print 'Case %d: the next triple peak occurs in %d days.' % (idx, triplePeak(p, e, i, d))
        idx += 1
    except:
        break 


编辑于 2016-04-26 14:20:59 回复(0)