中国剩余定理 ( POJ 1006 )










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
转化成线性同余方程组:
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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值