从一道程序员笔试题到中国剩余定理和一次同余方程组的通用解法

    此文描述的问题是由我参加的一家图形软件公司的一道笔试题扩展出来的,原题目是这样:一堆鸡蛋,3个3个数余2,5个5个数余1,7个7个数余6,问这堆鸡蛋最少有多少个?

    学过数论的朋友很容易知道,这其实是一个很经典的解一次同余方程组的数学题。当然即使你不知道怎么解同余方程组,用最笨的枚举法也可以很快求出本题的答案41,不过但凡有点求是精神的同志都不应该觉得满足于此,所以我又回忆了一下初等数论的相关理论知识,特此总结一下!

    对于这个问题用数学的语言来描述就是:

        N = 2(mod 3) = 1(mod 5) = 6(mod 7);

    求解最小N。

    由一首诗可以轻易得出求解算法:

   “ 三人同行七十稀,五树梅花甘一枝, 七子团圆正半月,除百零五便得知。”

    即解为:N = 2*70+1*21+6*15-105*n.(n为使得N不为负的最大正整数,这里就是2了)

    那么我们是怎么得到这个公式的呢?

    其实早在几千年前中国的一本《孙子算经》就已经提及这个问题的解法了,原文为:

“今有物,不知其数,三三数之,剩二,五五数之,剩三,七七数之,剩二,问物几何?” 
    答曰:“二十三”
    术曰:“三三数之剩二,置一百四十,五五数之剩三,置六十三,七七数之剩二,置三十,并之,得二百三十三,以二百一十减之,即得。凡三三数之剩一,则置七十,五五数之剩一,则置二十一,七七数之剩一,则置十五,即得。”

    《孙子算经》的“物不知数”题虽然开创了一次同余式研究的先河,但由于题目比较简单,甚至用试猜的方法也能求得,所以尚没有上升到一套完整的计算程序和理论的高度。真正从完整的计算程序和理论上解决这个问题的,是南宋时期的数学家秦九韶。秦九韶在他的《数书九章》中提出了一个数学方法“大衍求一术”(其实就是后来数学王子高斯提出的解同余方程的方法),系统地论述了一次同余式组解法的基本原理和一般程序。

     秦九韶为什么要把他的这一套计算程序和基本原理称为“大衍求一术”呢?这是因为其计算程序的核心问题是要“求一”。所谓“求一”,通俗他说,就是求“一个数的多少倍除以另一个数,所得的余数为一”。那么为什么要“求一”呢?我们可以从“物不知数”题的几个关键数字70、21、15中找到规律。

    我们可以看出解此题的关键在于如何确定70、21、15这3个数(105 = 3*5*7)。现简述如下:

    归结为一句话就是求3、5、7三个数两两组合相乘的k倍模另外一个数而余1的数 。这样说可能有点抽象,下面具体讲解下大家就会明白了:

    首先对于5、7两个数,即为:

            70 = 2*5*7  = 1(mod 3)

    其中k为2,所以很容易求出第一个70,同样的道理可以求出:

            21 = 3*7 = 1(mod 5)

            15 = 3*5 = 1(mod 7)

 

    理解了上例解法,我们不难得出著名的中国剩余定理(孙子定理)的一般数学形式了:

    一次同余方程组

             x = a1(mod m1)

             x = a2(mod m2)

             ...

             x = ak(mod mk)

    若m1,m2,......,mk这些数两两互质,且定义miMi = m1m2......mk以及CiMi = 1 (mod mi)。则此一次同余方程组的解为:

        x = a1M1C1 + a2M2C2 + ......+akMkCk (mod m)。

 

    所以我们可以很容易的把这个面试题推广为:

    一堆鸡蛋,3个3个数余a1,5个5个数余a2,7个7个数余a3,问这堆鸡蛋最少有多少个?

    甚至推广为:

    一堆鸡蛋,n1个n1个数余a1,n2个n2个数余a2,n3个n3个数余 a,....., nm个nm个数余am,问这堆鸡蛋最少有多少个?(其中n1,n2,....., nm互质)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值