3.2 生理周期 POJ 4148(中国剩余定理)

3.2 生理周期 

Note:读题懵,看了书上的解题方法更懵。

能用简单枚举或跳步枚举是因为,周期长度为23 28 33三数最小公倍数为三数相乘。相当于是一个极为特殊的数,但一般情况下并不能用这样的方法。

经查阅  该类题正规的解法为数论中的《中国剩余定理》应用。

附几篇就此定理的解释,待理解。

https://blog.csdn.net/qq_35747066/article/details/78111333

https://blog.csdn.net/tick_tock97/article/details/71313058

https://blog.csdn.net/destiny1507/article/details/81751168

问题描述:

人生来就有三个生理周期,分别为体力周期、情感周期和智力周期,它们的周期长度分别为23天,28天和33天。每一个周期中有一天是高峰。在高峰这一天,人会在相应的方面表现出色。例如,在治理周期的高峰,人会思维敏捷,注意力容易高度集中。因为三个周期的长度不同,所以通常三个周期的高峰不会在同一天。对于每个人,想知道何时三个高峰在同一天对于每个周期,会给出从当前年份的第一天开始到出现高峰的天数(不一定是第一次出现高峰的时间)。给定一个从当年第一天开始的天数,你的任务是输出从给定时间开始(不包括给定时间),下一次三个高峰在同一天的时间(距给定时间的天数)。例如,给定时间为10,下次出现三个高峰同一天的时间是12,则输出2(注意这里不是3)。

输入数据:

输入包含多组数据,每一组数据由4个整数组成,数据以-1 -1 -1 -1 结束。

4个整数 (p,e,i,d)分别表示(给定时间到体力,情感,智力高峰出现的天数;给定时间)。

所有时间是非负的并且小于或等于365,所求时间小于或等于21252。

输入样例:

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

输出样例:

Case1: the next triple peak occurs in 21252 days.
Case2: the next triple peak occurs in 21152 days.
Case3: the next triple peak occurs in 19575 days.
Case4: the next triple peak occurs in 16994 days.
Case5: the next triple peak occurs in 8910 days.
Case6: the next triple peak occurs in 10789 days.

解题思路:

解法1(暴力):从给定的时间开始,遍历到21252,找到最早出现的某一天,在这一天体力、情感和智力高峰均出现,即满足

(j-p)%23==0、(j-e)%33==0、(j-i)%33==0

解法2:检索时可以利用已经发现的高峰值来加速搜索过程。例如,若发现第102天是体力的高峰值,那么第103,104,105...124天都不可能是体力、情感和智力高峰均出现的时间,因此可以直接跳到第102+23 = 125天。这个优化策略可以概括为:若某项高峰值的时间已经出现,则该高峰值的出现周期可以作为搜索步长。

#include<cstdio>
#include<stdlib.h>
#include<iostream>
using namespace std;

int main(){
	int j, count=0;
	int p, e, i, d;
	cin  >> p >> e >> i >> d;
	
	while(p != -1){
		count++;
		for(j = d+1; j < 21252; j++)//枚举每一天找到体力高峰
			if((j-p)%23==0)         //找到体力高峰
				break;
		for(; j < 21252; j = j + 23)//每隔23天一个体力高峰,枚举体力高峰
			if((j-e)%28==0)
				break;              //找到情感高峰
		 for(; j < 21252; j = j + 23*28)//每隔23*28天一个公共高峰,枚举每一个公共高峰
			 if((j-i)%33==0)
				 break;              //找到三个周期的公共高峰
		 printf("Case %d:the next triple peak occurs in %d days.\n", count, j-d);
	     cin >> p >> e >> i >> d;
	}

	system("pause");
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值