1. 程式人生 > >HDU1370(中國剩余定理)

HDU1370(中國剩余定理)

led link edit d+ 求逆 stat blog 中國 main

昨天我細致一想,發現自己之前的分類(用OJ來劃分,毫無意義啊。)太失敗了,所以我又一次劃分了一下大分類,在分到數論的時候,我就想起了中國剩余定理了。於是乎今天就刷了一題中國剩余定理的題目了。話說太久沒作數學題。導致我連例子都調了好多次(在算逆元時候老是算錯~煩惱!),好在提交時候是1A。

題目的意思就是:人有三個周期,記為p,e,i,周期天數分別為23,28,33,如今給定你三個時間a,b,c,和一個天數d,a,b,c分別表示p,e,i出現的天數,問下一次出現的大於d的天數是今年的第幾天,即輸出天數X-d.由於23,28,33互素,所以就能夠用中國剩余定理啦!

否則的話,僅僅能分解了!

上學期學數論的時候非常多時候多是要自己分解~

對於28*33,23*33,23*28分別求逆元(不知道什麽是逆元的話。你能夠理解為n是n‘ mod m的逆元,當且僅當n*n‘ mod m=1),得到6,19,2.

之後答案就是ans=6*28*33*a+19*23*33*b+2*23*28*c + k*(23*28*33),這個k要取到ans>d

ACcode

/***********************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : [email protected] 
	> Time   : 2014年06月09日 星期一 07:34:32
 **********************************************************/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int b[5];
int main(){

    int a;
    //23,28,33
    int m=23*28*33;
    int M[]={6,19,2};
    int M_[]={28*33,23*33,23*28};
    cin>>a;

    int ind=1;
    while(cin>>b[0]>>b[1]>>b[2]>>b[3]){
        if(b[0]==-1&&b[1]==-1&&b[2]==-1&&b[3]==-1){
            return 0;
        }
        int ans=0;
        for(int i=0;i<3;i++){
         ans=(ans+M[i]*M_[i]*b[i])%m;
        }
        while(ans<=b[3]){
            ans+=m;
        }
        cout<<"Case "<<(ind++)<<": the next triple peak occurs in "<<ans-b[3]<<" days."<<endl;

    }

return 0;
}



HDU1370(中國剩余定理)