您的位置:首页 > 其它

lightoj 1319 Monkey Tradition(中国剩余定理)

2017-12-25 15:02 190 查看

题目:

In ‘MonkeyLand’, there is a traditional game called “Bamboo Climbing”. The rules of the game are as follows:

1) There are N monkeys who play this game and there are N bamboos of equal heights. Let the height be L meters.

2) Each monkey stands in front of a bamboo and every monkey is assigned a different bamboo.

3) When the whistle is blown, the monkeys start climbing the bamboos and they are not allowed to jump to a different bamboo throughout the game.

4) Since they are monkeys, they usually climb by jumping. And in each jump, the ith monkey can jump exactly pi meters (pi is a prime). After a while when a monkey finds that he cannot jump because one more jump may get him out of the bamboo, he reports the remaining length ri that he is not able to cover.

5) And before the game, each monkey is assigned a distinct pi.

6) The monkey, who has the lowest ri, wins.

解题思路:

具体解法分三步:

找出三个数:从3和5的公倍数中找出被7除余1的最小数15,从3和7的公倍数中找出被5除余1 的最小数21,最后从5和7的公倍数中找出除3余1的最小数70。

用15乘以2(2为最终结果除以7的余数),用21乘以3(3为最终结果除以5的余数),同理,用70乘以2(2为最终结果除以3的余数),然后把三个乘积相加15∗2+21∗3+70∗215∗2+21∗3+70∗2得到和233。

用233除以3,5,7三个数的最小公倍数105,得到余数23,即233%105=23233%105=23。这个余数23就是符合条件的最小数。

  就这么简单。我们在感叹神奇的同时不禁想知道古人是如何想到这个方法的,有什么基本的数学依据吗?

中国定理讲解:

  我们将“孙子问题”拆分成几个简单的小问题,从零开始,试图揣测古人是如何推导出这个解法的。

  首先,我们假设n1n1是满足除以3余2的一个数,已知n1n1满足除以3余2,能不能使得n1+n2n1+n2的和仍然满足除以3余2?进而使得n1+n2+n3n1+n2+n3的和仍然满足除以3余2?

为使n1+n2+n3n1+n2+n3的和满足除以3余2,n2n2和n3n3必须是3的倍数。
为使n1+n2+n3n1+n2+n3的和满足除以5余3,n1n1和n3n3必须是5的倍数
为使n1+n2+n3n1+n2+n3的和满足除以7余2,n1n1和n2n2必须是7的倍数。


  

  因此,为使n1+n2+n3n1+n2+n3的和作为“孙子问题”的一个最终解,需满足:

  

n1n1除以3余2,且是5和7的公倍数。

n2n2除以5余3,且是3和7的公倍数。

n3n3除以7余2,且是3和5的公倍数。

  所以,孙子问题解法的本质是从5和7的公倍数中找一个除以3余2的数n1,从3和7的公倍数中找一个除以5余3的数n2,从3和5的公倍数中找一个除以7余2的数n3,再将三个数相加得到解。在求n1,n2,n3时又用了一个小技巧,以n1为例,并非从5和7的公倍数中直接找一个除以3余2的数,而是先找一个除以3余1的数,再乘以2。也就是先求出5和7的公倍数模3下的逆元,再用逆元去乘余数。

  这里又有一个数学公式,如果a%b=ca%b=c,那么(a∗k)%b=a%b+a%b+…+a%b=c+c+…+c=k∗c(k>0)(a∗k)%b=a%b+a%b+…+a%b=c+c+…+c=k∗c(k>0),也就是说,如果一个除法的余数为cc,那么被除数的kk倍与除数相除的余数为k∗ck∗c。展开式中已证明。

  最后,我们还要清楚一点,n1+n2+n3n1+n2+n3只是问题的一个解,并不是最小的解。如何得到最小解?我们只需要从中最大限度的减掉掉3,5,7的公倍数105即可。道理就是前面讲过的定理“如果a%b=ca%b=c,则有(a−k∗b)%b=c(a−k∗b)%b=c”。所以(n1+n2+n3)%105(n1+n2+n3)%105就是最终的最小解。

这样一来就得到了中国剩余定理的公式:

欧几里得算法:

原理:a和b的最大公约数等于b和a%b

证明:

a可以表示成a = kb + r(a,b,k,r皆为正整数,且r小于b)

则r = a mod b 假设d是a,b的一个公约数,记作d|a,d|b,即a和b都可以被d整除。 而r = a - kb,两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数,因此d|r 因此d也是b,a mod b的公约数 假设d是b,a mod b的公约数, 则d|b,d|(a-k*b),k是一个整数。 进而d|a.因此d也是a,b的公约数 因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。

拓展欧几里得算法:

假设当前我们要处理的是求出 a 和 b的最大公约数,并求出 x 和 y 使得 a*x + b*y= gcd ,而我们已经求出了下一个状态:b 和 a%b 的最大公约数,并且求出了一组x1 和y1 使得: b*x1 + (a%b)*y1 = gcd , 那么这两个相邻的状态之间是否存在一种关系呢?

我们知道: a%b = a - (a/b)*b(这里的 “/” 指的是整除,例如 5/2=2 , 1/3=0),那么,我们可以进一步得到:

gcd = b*x1 + (a-(a/b)*b)*y1
= b*x1 + a*y1 – (a/b)*b*y1
= a*y1 + b*(x1 – a/b*y1)


对比之前我们的状态:求一组 x 和 y 使得:a*x + b*y = gcd ,是否发现了什么?

这里:

x = y1
y = x1 – a/b*y1


求解形如 a*x +b*y = c 的通解,但是一般没有谁会无聊到让你写出一串通解出来,都是让你在通解中选出一些特殊的解,比如一个数对于另一个数的乘法逆元

什么叫乘法逆元?

a*x + m*y = 1
这里,我们称 x 是 a 关于 m 的乘法逆元
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: