poj2977:生理周期

poj2977:生理周期
参考案例

0 0 0 0
0 0 0 100
5 20 34 325
4 5 6 7
283 102 23 320
203 301 203 40
// 21252
// 21152
// 19575
// 16994
// 8910
// 10789

解法①
当输入时就有a == b == c时,相当于输出23,28,33三个数的最小公倍数
可以lcm(lcm(23,28),lcm(23,33)) (两两lcm)

#include<iostream>
using namespace std;
int a,b,c,d;
int main()
{
    
    
	cin>>a>>b>>c>>d;
	if(a==b&&b==c)//特判,如果一开始三个日期就重合,不会进入while循环,此时手动将a+23; 
		a+=23; 
	while(a!=b||b!=c)
	{
    
    
		if(a<b) a+=23;
		if(b<c) b+=28;
		if(c<a) c+=33;
	}
	printf("%d",a-d);
}

解法②
注意循环for中的条件

#include<iostream>
using namespace std;
int a,b,c,d;
int main()
{
    
    
	cin>>a>>b>>c>>d;
	for(int i=d+1;i<=d+21252;i++)
		if((i-a)%23==0)
			if((i-b)%28==0)
				if((i-c)%33==0)
					{
    
    
						printf("%d",i-d);
						return 0;
					}
	
}

解法③
基于解法①的优化
将原问题分治为寻找三个不同的周期.
跳着搜索

#include<iostream>
using namespace std;
int a,b,c,d,ans;
int main()
{
    
    
	cin>>a>>b>>c>>d;
	ans=d+1;
	for(;ans<=21252;ans++)
		if((ans-a)%23==0)
			break;
	for(;ans<=21252;ans+=23)
		if((ans-b)%28==0)
			break;
	for(;ans<=21252;ans+=23*28)
		if((ans-c)%33==0)
			break;
	printf("%d",ans-d);
}
#include <iostream>
using namespace std;
int main(){
    
    
	int a, b, c, d,ans;
	cin >> a >> b >> c >> d;
		for(ans = d + 1; (ans - a) % 23; ++ans); //从给定的d+1天开始找到第一个体力高峰
		for(; (ans - b) % 28; ans += 23);  //对每个体力高峰, 判断是否是情感高峰 
		for(; (ans - c) % 33; ans += 23 * 28); //对每个体力情感高峰, 判断是否是智力高峰
		printf("%d", ans - d);
	}

猜你喜欢

转载自blog.csdn.net/weixin_49640089/article/details/114288026
今日推荐