poj 1006 中国剩余定理

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

     再过多少天后三个峰值同时出现。


poj 1006 中国剩余定理_第1张图片

 

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
int a[105],m[105];//a[0],m[0]不使用
int n;
void extendgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1;
        y=0;
    }
    else
    {
        extendgcd(b,a%b,y,x);
        y-=x*(a/b);
    }
}
int crt()
{
    int M=1;
    for(int i=1;i<=n;i++)
        M*=m[i];
    int x=0;//x为同余方程组的解
    for(int i=1;i<=n;i++)
    {
        int Mi=M/m[i];
        int x0,y0;
        extendgcd(Mi,m[i],x0,y0);//求得的x0为Mi的逆元Mi^-1
        x=(x+(a[i]*Mi*x0)%M)%M;
    }
    if(x<0)
        x+=M;
    return x;
}
int main()
{
    int p,e,i;
    int t=1;
    while(cin>>p>>e>>i)
    {
        int d;
        cin>>d;
        if(p==-1||e==-1||i==-1||d==-1)
            return 0;
        a[1]=p;
        a[2]=e;
        a[3]=i;
        m[1]=23;
        m[2]=28;
        m[3]=33;
        n=3;//n为项数
        int x=crt();
        if(x<=d)
            x+=21252;
        cout<<"Case "<<t++<<": the next triple peak occurs in "<<x - d<<" days."<<endl;
    }
    return 0;
}

模板:

全局:a[],m[],n
int crt()//	中国剩余定理,返回最小非负整数解x
{
    int M=1;
    for(int i=1;i<=n;i++)
        M*=m[i];
    int x=0;//x为同余方程组的解
    for(int i=1;i<=n;i++)
    {
        int Mi=M/m[i];
        int x0,y0;
        extendgcd(Mi,m[i],x0,y0);//求得的x0为Mi的逆元Mi^-1
        x=(x+(a[i]*Mi*x0)%M)%M;
    }
    if(x<0)
        x+=M;
    return x;
}
int main()
{
构造数组a[],m[],n;
cout<<crt;
}


你可能感兴趣的:(中国剩余定理)