poj 1006 生理周期 中国剩余定理

题意:人的身体素质,情绪状况,智力水平是在不断波动。时高时低。它们的周期分别是23,28,33天,顶峰会出现在周期中。给定p,e,i分别代表起三种水平从当年到达高峰的天数。对于每个周期,会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间)。你的任务是给定一个从当年第一天开始数的天数(d),输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一天的时间(距给定时间的天数)。求最少天数。

poj 1006 :http://poj.org/problem?id=1006&lang=zh-CN&change=true

思路:假设在第x天同时达到顶峰。
x=p+k1*m0;
x=e+k2*m1;
x=I+k3*m2;
k1,k2,k3为整数.
化为同余方程组
p=x%m0;
e=x%m1;
I=x%m2;
mi为给定的周期,均为质数,可以用中国剩余定理求x。x还要减去起始位置d才是答案

#include<cstdio>
#define ll long long
using namespace std;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
	if(!b)
	{
		x=1;
		y=0;
		d=a;
	}
	else
	{
		exgcd(b,a%b,d,y,x);
		y-=x*(a/b);
	}
}
ll inv(ll a,ll p)//求a关于模p的逆元 
{
	ll x,y,d;
	exgcd(a,p,d,x,y);
	x=((x%p)+p)%p;
	return x;
}
ll china(int n,ll *a,ll *m)
{
	ll ret=0;
	ll M=1;
	for(int i=0;i<n;i++)M*=m[i];
	for(int i=0;i<n;i++)
	{
		ll w = M/(m[i]);
		ret=(ret+w*inv(w,m[i])*a[i])%M;
	}
	return (ret+M)%M;
}
int main()
{
	ll p,e,i,d;
	int cas=0;
	while(~scanf("%lld%lld%lld%lld",&p,&e,&i,&d))
	{
		ll a[3],m[3];
		if(p==-1&&e==-1&&i==-1&&d==-1)break;
		m[0]=23;m[1]=28;m[2]=33;
		a[0]=p;a[1]=e;a[2]=i;
		ll ans=china(3,a,m);
		ll MOD=m[0]*m[1]*m[2];
		ans=((ans-d)%MOD+MOD)%MOD;
		printf("Case %d: the next triple peak occurs in %lld days.\n",++cas,ans?ans:MOD);
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值