POJ 1006题解
题目描述:
人的体力、情感、智力的峰值分别每隔23、28、33天出现一次,给出p、e、i分别代表上次体力、情感、智力的峰值出现的时间,d表示当前时间,给出的变量的值都是相对于0天来说的,求距离下次三个峰值在同一天出现还要多少天
题目分析:
根据题意,三个峰值同时出现的时间距离任意一个峰值上次出现的时间一定是该峰值出现的周期的整数倍,令a, b, c分别代表倍数,n代表三个峰值同时出现的时间
得到方程:
p + 23 * a = n
e + 28 * b = n
i + 33 * c = n
e + 28 * b = n
i + 33 * c = n
转化成线性同余方程组:
n MOD 23 = p
n MOD 28 = e
n MOD 33 = i
按照上述方法导出最小解的表达式即可。
需要注意刚好整除的情况,算出结果小于等于0的时候要加上一个周期( 23,28,33 的最小公倍数)
Code:
#include <cstdio>
#include <iostream>
using namespace std;
int CRT( int p, int e, int i, int d )
{
int x;
int y;
int z;
for( int k = 1; ; k++ )
{
if( ( 28 * 33 * k ) % 23 == 1 )
{
x = k;
break;
}
}
for( int k = 1; ; k++ )
{
if( ( 23 * 33 * k ) % 28 == 1 )
{
y = k;
break;
}
}
for( int k = 1; ; k++ )
{
if( ( 23 * 28 * k ) % 33 == 1 )
{
z = k;
break;
}
}
return ( 28 * 33 * x * p + 23 * 33 * y * e + 23 * 28 * z * i ) % ( 23 * 28 * 33 ) - d;
}
int main()
{
int p, e, i, d;
int cas = 1;
while( scanf( "%d%d%d%d", &p, &e, &i, &d ), ( p != -1 && e != -1 && i != -1 && d != -1 ) )
{
int ans = CRT( p, e, i, d );
ans = ans <= 0 ? ( ans + 23 * 28 * 33 ) : ans;
printf( "Case %d: the next triple peak occurs in %d days.\n", cas++, ans );
}
return 0;
}