• 中国剩余定理


    韩信点兵的故事大家一定都听说过,韩信让士兵分别3个3个报数多2人,5个5个报数多4人,7个7个报数多6人,通过每次报数的余数计算出军队的人数。


    其实,韩信所做的,就是解了三个同余方程:

    x≡2 (mod 3)

    x≡4 (mod 5)

    x≡6 (mod 7)

    怎么解呢?古人想了一个聪明的办法:

    找一个数x1,使得它是5和7的倍数,而除3余2,

    找一个数x1,使得它是7和3的倍数,而除5余4,

    找一个数x1,使得它是5和3的倍数,而除7余6,

    然后三个数加起来,就一定满足这个条件,而且解周期为3*5*7


    中国剩余定理

    我们把这个算法拓展,对于任意的方程组x≡bi (mod mi)
    即:
    x≡b1 (mod m1)
    x≡b2 (mod m2)
    x≡b3 (mod m3)
    ......
    x≡bn (mod mn)

    其中m都是互质的

    那么我们对于每一个方程,算出一个xi,使得xi满足:xi≡1 (mod mi) 且xi≡0 (mod mj)【j!=i】
    也就是说xi是其他m的倍数,而模mi余1
    y*(N/mi)≡1 (mod mi)  【N=m1*m2*m3*......mn】用扩展欧几里得算法就可以解出了
    那么最终的x=(x1*b1+x2*b2+x3*b3+......xn*bn) mod N   【N=m1*m2*m3*......mn】

    【我懒就先不打代码了= =】


    水题:POJ1006

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    using namespace std;
    const int maxn=100005,INF=2000000000,P=1000000007;
    
    void exgcd(int a,int b,int& d,int& x,int& y){
    	if(!b) {d=a;x=1;y=0;}
    	else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
    }
    
    int main(){
    	int N=21252,A[4],T[4]={0,23,28,33},t,ans=0,cnt=0;
    	while(cin>>A[1]>>A[2]>>A[3]>>t){
    		if(t==-1) break;
    		ans=0;
    		cnt++;
    		for(int i=1;i<=3;i++){
    			int x,y,a=T[i],b=N/T[i],d;
    			exgcd(a,b,d,x,y);
    			ans=(ans+y*b*A[i])%N;
    		}
    		ans=((ans-t)%N+N)%N;
    		if(!ans) ans+=N;
    		printf("Case %d: the next triple peak occurs in %d days.
    ",cnt,ans);
    	}
    	return 0;
    }
    



  • 相关阅读:
    UVA 10828
    素数推断算法(高效率)
    POJ1611 The Suspects (并查集)
    Android AES加密算法及事实上现
    C语言中的内存对齐
    OpenCV——老照片效果
    uuid 学习
    OpenCV——PS 滤镜, 浮雕效果
    加密算法之BLOWFISH算法
    OpenCV——照亮边缘
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282877.html
Copyright © 2020-2023  润新知