您的位置:首页 > 其它

求两个数的最大公约数--2012腾讯实习生招聘笔试题,由此想到狼追兔子问题

2012-04-09 10:36 405 查看
1、 int func(int m,int n)

{

if(m%n==0)

return n;

else return func(n,m%n);

}

求func(2012,2102);

这个递归程序实际上是示m和n的最大公约数。

上面的程序和下面的程序是等价的:

int func(int m,int n)

{

return (!n)?m:func(n,m%n);

}

(求m,n的最大公约数)

该程序的设计思想是求m和n(m>n)的最大公约数转化为求n和m%n的公约数。证明如下:设m%n=k,则m=nt+k,其中t为整数,设m n的最大公约数为p,则m/p=(nt+k)/p,因为p是m和n的最大公约数,那么m/p,n/p肯定是整数,所以k/p肯定也是整数,所以p也是k的最大公约数,所以求m和n(m>n)的最大公约数转化为求其中一个小数的和m%n的公约数,可用上述两种方法实现。或者这样理解:求两个数的最大公约数,那么这两个数肯定可以被最大公约数整除,也就是说,可以把这两个数分别分成不同的份数,每一份的大小是最大公约数的大小,一个数对另一个数取余的时候,剩下的那部分,还是可以被分成很多份,每份大小是最大公约数的大小,这样循环很多次,最后就剩下一份了,这一份就是最大公约数了

如何求两个数的最小公倍数呢?

m和n的最大公约数为k,则m和n的最小公倍数则是k*(m%k)*(n%k)

由此问题想到狼追兔子问题:

Wolf and Rabbit

There is a hill with n holes around. The holes are signed from 0 to n-1.

A rabbit must hide in one of the holes. A wolf searches the rabbit in anticlockwise order. The first hole he get into is the one signed with 0. Then he will get into the hole every m holes. For example, m=2 and n=6, the wolf will get into the holes which are
signed 0,2,4,0. If the rabbit hides in the hole which signed 1,3 or 5, she will survive. So we call these holes the safe holes.

不妨让兔子躲在1号洞,因为如果狼能从0号洞到1号洞,则它一定能够从1号洞到2号,3号,..n-1号洞,兔子无论躲在哪里都难逃厄运。换而言之,若有安全的洞,1号洞必然是其中之一。

再来看狼的运动。狼的第i次运动后的洞址应该是(m*i) mod n,若(m*i) mod n=1,即狼第i次运动后到达1号洞,则可以证明gcd(m,n)=1,其中gcd(m,n)表示m和n的最大公约数。因为若gcd(m,n)=k,设m'*k=m,n'*k=n,则(m'*k*i)mod(n'*k)=1,于是存在正整数t,使得m'*k*i=t*n'*k+1,两边同除以k得到:m'*i=t*n'+1/k。因为m'*i和t*n'同为正整数,所以1/k为整数,因此k只能为1。也就是gcd(m,n)=1,则不存在安全洞,若存在,刚不存在安全洞。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐