中国剩余定理

http://poj.org/problem?id=1006

题意 : 周期分别为 23 , 28 , 33 的三个时期 , 给出每个时期出现高潮的时间 a1 a2 a3 , 从d天开始,求三个时期共同到达高潮期要过多少天。

//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include ;
#include 
#include 
#include 
#include 
#include 
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define PI acos(-1)
using namespace std;
typedef long long ll ;
const int mod = 1e9+7 ;
int a[10] , x , y , d;

//拓展欧几里得 求temp*x+m*y = a , 中的x
void gcd(int a , int b , int &d , int &x , int &y)
{
    if(b == 0)
    {
        x = 1 ;
        y = 0 ;
        d = a ;
    }
    else{
        gcd(b , a%b , d , x , y);
        int t = x ;
        x = y ;
        y = t - (a/b)*y ;
    }
}

int cal(int a , int b , int c)
{
    gcd(a , b , d , x , y);
    int t = b / d ;
    return (x*c % t + t) % t ;
}

int CRT(int a[] , int m[] , int n)
{
    int M = 1 , ans = 0 ;
    for(int i = 0 ; i < n ; i++)//求所有mod数的最大公倍数,因为两两互质全部乘起来即可
        M *= m[i];
    for(int i = 0 ; i < n ; i++)//分部求和
    {
        int temp = M / m[i] ;//除去本身,就互质了
        ans = (ans + cal(temp , m[i] , a[i])*temp)% M;
    }
    return ans % M ;
}

int main()
{
    int a1 , a2 , a3 , day , ans = 0;
    int a[10] , m[10] = {23 , 28 , 33};//a数组余数数组,m模数数组
    while(~scanf("%d%d%d%d" , &a1 , &a2 , &a3 , &day))
    {
        if((a1 == -1) & (a2 == -1) & (a3 == -1) & (day == -1)) break ;
        a[0] = a1 , a[1] = a2 , a[2] = a3 ;
        int t = CRT(a , m , 3);
        if(t - day <= 0)
        {
            t += 21252 ;
        }
        cout << "Case " << ++ans << ": the next triple peak occurs in " << t - day << " days." << endl ;
    }

    return 0 ;
}

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