您的位置:首页 > 其它

【POJ1006】Biorhythms——中国剩余定理

2017-08-28 19:58 281 查看

题目链接

题目大意:

人自出生起就有体力,情感和智力三个生理周期,分别为23,28和33天。一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。

分析:

首先有必要知道一下中国剩余定理:

对于两两互质的数m1,m2...mi,要求一个最小的x使得满足

              x%m1=a1;

              x%m2=a2;

               ......

              x%mi=ai。

那么

#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long LL;
using namespace std;
int k[4],m[4],M=23*28*33;
int read()
{
int ans=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
return ans*f;
}
void ex_gcd(int a,int b,int& x,int& y)
{
if(b==0){
x=1;
y=0;
return;
}
ex_gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
}
int China(int k[],int m[])
{
int x,y,ans=0;
for(int i=1;i<=3;i++){
int t=M/m[i];
ex_gcd(t,m[i],x,y);
ans=(ans+k[i]*x*t)%M;
}
if(ans<0)ans+=M;
return ans;
}
int main()
{
int a,b,c,d,sum=0;m[1]=23;m[2]=28;m[3]=33;
a=read();b=read();c=read();d=read();
while(a!=-1){
k[1]=a;k[2]=b;k[3]=c;
int day=China(k,m);
while(day<=d)day+=21252;
printf("Case %d: the next triple peak occurs in %d days.\n",++sum,day-d);
a=read();b=read();c=read();d=read();
}
return 0;
}
POJ1006  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: