<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Change Dir

    先知cd——熱愛生活是一切藝術(shù)的開始

    統(tǒng)計(jì)

    留言簿(18)

    積分與排名

    “牛”們的博客

    各個(gè)公司技術(shù)

    我的鏈接

    淘寶技術(shù)

    閱讀排行榜

    評論排行榜

    復(fù)習(xí)中國剩余定理

    前幾天女朋友問我一個(gè)題目:一次酒店宴席安排賓客就座吃飯,5人一桌剩4人,7人一桌剩6人,9人一桌剩8人,11人一桌正好。問宴席共有多少人?

    一眼看去:中國剩余定理,但是答案和過程的獲取的那個(gè)揪心啊,讓我意識(shí)到,當(dāng)初看過的數(shù)論的東西都忘掉了,像這些有可能在密碼學(xué)中用到的算法知識(shí),看密碼學(xué)和算導(dǎo)的時(shí)候都記得很清楚,也拿實(shí)際題目演練過,但是時(shí)間一長還是忘記了。現(xiàn)在把功課補(bǔ)一補(bǔ),寫篇文章紀(jì)念一下~~~

    中國剩余定理:設(shè)n=n1*n2*...*nk,其中因子ni兩兩互質(zhì)。考慮如下對應(yīng)關(guān)系 a <-> (a1,a2,...,ak)其中 ai = a mod ni
    如果a<->(a1,a2,...,ak),b<->(b1,b2,...,bk)
    那么(a+b) mod n <-> ((a1+b1) mod n1, ..., (ak+bk) mod nk)
    (a-b) mod n <-> ((a1-b1) mod n1, ... , (ak-bk) mod nk)
    (ab) mod n <-> (a1b1 mod n1, ... , akbk mod nk)

    這個(gè)定理有兩個(gè)重要推論:
    (1)如果n1, n2, ... , nk兩兩互質(zhì),n=n1*n2*...*nk,則對任意整數(shù)a1, a2, ... , ak,方程組 x=ai (mod ni) 關(guān)于未知量x對模n有唯一解。
    (2)如果n1, n2, ... , nk兩兩互質(zhì),n=n1*n2*...*nk,則對所有整數(shù)x和a,x=a (mod ni) 當(dāng)且僅當(dāng) x=a (mod n)。

    針對這個(gè)問題,這個(gè)定理怎么用呢?
    n1=5,n2=7,n3=9,n4=11。 n=n1*n2*n3*n4 = 3465。我們現(xiàn)在要求的就是a,那么與a的對應(yīng)關(guān)系a1,a2,a3,a4是什么呢?
    利用公式:a1 = a mod n1 = 4,a2 = a mod n2 = 6,a3 = a mod n3 = 8,a4 = a mod n4 = 0。
    如此,n序列和a序列已經(jīng)都初始化了。n也計(jì)算出來了。問題就轉(zhuǎn)化為知道這些輸入,如何能計(jì)算出a來。
    首先確定m序列,mi是什么呢?定義mi=n/ni。這是一個(gè)中間步驟,目的是為了定義c序列ci = mi * (mi-1 mod ni)。
    因?yàn)閙i和ni互質(zhì),mi-1 mod ni存在。最后計(jì)算a 的方法即 a = (a1*c1 + a2*c2 + ... + ak*ck) (mod n)。

    具體細(xì)節(jié)不再多寫了,抄書的工作沒有意義。有興趣的朋友們建議多翻書吧。定理書上都有,就針對這一問題,解決方法上代碼。

    算法實(shí)現(xiàn)如下:
     1/**
     2 * 
     3 */

     4package algorithm.math;
     5
     6/**
     7 * @author Jia Yu
     8 * @date   2010-11-11
     9 */

    10public class ChinaModule {
    11
    12    /**
    13     * Return the greatest common divisor.
    14     */

    15    public static long gcd( long a, long b )
    16    {
    17        if( b == 0 )
    18            return a;
    19        else
    20            return gcd( b, a % b );
    21    }

    22
    23      // Internal variables for fullGcd
    24    private static long x;
    25    private static long y;
    26
    27    /**
    28     * Works back through Euclid's algorithm to find
    29     * x and y such that if gcd(a,b) = 1,
    30     * ax + by = 1.
    31     */

    32    private static void fullGcd( long a, long b )
    33    {
    34        long x1, y1;
    35
    36        if( b == 0 )
    37        {
    38            x = 1;
    39            y = 0;
    40        }

    41        else
    42        {
    43            fullGcd( b, a % b );
    44            x1 = x; y1 = y;
    45            x = y1;
    46            y = x1 - ( a / b ) * y1;
    47        }

    48    }

    49
    50    /**
    51     * Solve ax == 1 (mod n), assuming gcd( a, n ) = 1.
    52     * @return x.
    53     */

    54    public static long inverse( long a, long n )
    55    {
    56        fullGcd( a, n );
    57        return x > 0 ? x : x + n;
    58    }

    59
    60    public static long china(long[] n, long[] a) {
    61        // TODO Auto-generated method stub
    62        long n_total = 1L;
    63        final int len = n.length;
    64        for(int i=0;i<len;i++){
    65            n_total *= n[i];
    66        }

    67        
    68        long []m = new long[len];
    69        for(int i=0;i<len;i++){
    70            m[i] = n_total / n[i];
    71        }

    72        
    73        long []c = new long[len];
    74        for(int i=0;i<len;i++){
    75            c[i] = m[i] * inverse(m[i],n[i]);
    76        }

    77        
    78        long a_total = 0L;
    79        for(int i=0;i<len;i++){
    80            a_total += (a[i]*c[i]) % n_total;
    81        }

    82        a_total %= n_total;
    83        return a_total;
    84    }

    85
    86       
    87    /**
    88     * @param args
    89     */

    90    public static void main(String[] args) {
    91        // TODO Auto-generated method stub
    92        long n[] = {5,7,9,11};
    93        long a[] = {4,6,8,0};
    94        //long n[] = {3,5,7};
    95        //long a[] = {2,3,2};
    96        System.out.println(china(n,a));
    97    }

    98}

    99


    其中的GCD方法是歐幾里得求最大公約數(shù)算法,fullgcd是擴(kuò)展歐幾里得算法,inverse是利用擴(kuò)展歐幾里得方法求乘法逆元的方法,china是通過輸入數(shù)組求目標(biāo)數(shù)的方法。
    最后得到結(jié)果2519。即總共2519名賓客。

    當(dāng)時(shí)沒算出來,過了一會(huì)女朋友來短信:“我用excel做出來了”~~~~我狂汗!

    posted on 2010-11-18 10:10 changedi 閱讀(2669) 評論(1)  編輯  收藏 所屬分類: 算法

    評論

    # re: 復(fù)習(xí)中國剩余定理[未登錄] 2010-11-18 13:30 abc

    效率雖然低些,可也能算出來。
    for (int i=11;i<9999;i=i+11){

    if(i%5==4 && i%7==6 && i%9==8){
    System.out.println("The number is :" + i);
    break;
    }

    }
    The number is :2519
    The number is :5984
    The number is :9449
      回復(fù)  更多評論   

    主站蜘蛛池模板: 亚洲电影免费观看| 无码AV动漫精品一区二区免费| 亚洲国产一区二区三区青草影视| 久久精品国产亚洲av高清漫画| 久久亚洲国产精品| 国产免费小视频在线观看| 国产无遮挡吃胸膜奶免费看视频| 在线免费观看视频你懂的| 国产成人免费a在线资源| 免费播放特黄特色毛片| 成人亚洲网站www在线观看| 亚洲国产V高清在线观看| 亚洲国产香蕉人人爽成AV片久久 | 亚洲av无码成人精品国产| 亚洲乱码中文字幕在线| 亚洲第一se情网站| 国产亚洲综合久久| 羞羞视频免费网站日本| 国产精品成人啪精品视频免费| a级成人毛片免费图片| 免费不卡在线观看AV| 国产精品免费网站| 男女啪啪永久免费观看网站| 亚洲Av无码乱码在线播放| 亚洲桃色AV无码| 亚洲国产成人超福利久久精品| ass亚洲**毛茸茸pics| 亚洲国产精品成人午夜在线观看 | 亚洲欧洲精品在线| 亚洲天然素人无码专区| 日韩精品免费一线在线观看| 中文字幕久无码免费久久| 亚洲开心婷婷中文字幕| 亚洲一区中文字幕久久| 亚洲日本久久久午夜精品| 老司机福利在线免费观看| a毛片在线免费观看| 在线观看H网址免费入口| 免费a级毛片网站| 亚洲AV日韩AV高潮无码专区| 一本色道久久88—综合亚洲精品 |