鸡兔同笼问题的常用解法及有解条件

题目来源:《算法竞赛入门经典》例题1-4 鸡兔同笼

【题目描述】

已知鸡和兔的总数量为n,总腿数为m。输入n和m,依次输出鸡的数目和兔的数目。如果无解,则输出No answer。

【样例输入】

14 32

【样例输出】

12 2

【样例输入】

10 16

【样例输出】

No answer

一、求解方法

求解鸡兔同笼问题,有很多种方法,这里介绍常用的3种方法:

1、假设法。这是最常用的方法。假设全是腿少(或腿多)的动物,这里假设全是鸡,那么腿数应该是2n,实际腿数为m,实际比假设腿数多了m-2n只。每将一只鸡替换为兔会增加2条腿,所以用(m-2n)/2就是兔的只数。

这样用字母可能比较抽象,可以用具体的数再说明一下。如假设鸡和兔的数量为8只,有22条腿。假设全是鸡,8只鸡的腿数为2×8=16只,实际腿数为22条,实际比假设腿数多了22-16=6条。如图所示,每将一只鸡替换为兔会增加2条腿,故增加了6条腿应是替换了6/2=3只,即兔子有3只,鸡有8-3=5只。

鸡兔同笼问题的常用解法及有解条件_第1张图片

2、吹哨砍脚法。这是最好理解的方法。假设长官每吹一次哨,就要砍掉每只动物一只脚,那么连吹两次哨,鸡的脚就被砍完了,这时还剩m-2n只脚,而这些脚全部是兔子的,每只兔子还剩2只脚,所以兔子有(m-2n)/2只。

3、方程法。设鸡有x只,兔有y只,则x+y=n,2x+4y=m,联立解得x=(4n-m)/2,y=n-x=(m-2n)/2。

二、有解条件

鸡和兔都是动物,所以题目有解的条件就是:鸡和兔的只数都是非负整数。

即:x>=0 且 y>=0 且 4n-m%2==0

注:没有必要再判断(m-2n)/%==0,因为如果x是整数,y必然为整数,只要判断它们中的一个为整数即可。

因为4n/2必然是整数,所以4n-m%2==0可简化为m%2=0。

解得:x>=0 且 y>=0 且 m%2==0

m%2==0的现实意义其实就是:鸡和兔的总腿数要为偶数。显然这是符合常识的。但是注意这个条件是推出来的,不是具有普遍意义的条件,因为动物的腿数可能是奇数,这时这个结论就不适用了。具有普遍意义的条件还是两种动物的只数都是非负整数。

也就是说,只要腿的总数是偶数,就能保证最后得出的鸡和兔的只数都是整数。

三、问题通用化

把这个问题再通用化,假设A、B两种动物,A、B总数量为n,总腿数为m,A有a条腿,B有b条腿。设A的数数为x,B的数量为y。

解得:x = (bn-m)/(b-a),y = (m-an)/(b-a)

如果我们假设b>a,那么这个答案就可以直接用假设法解释,b-a就是每只腿多动物比每只腿少动物多出的腿数。bn就是假设全部是腿多的动物的腿数,m是实际腿数,bn-m就是在假设全部是腿多动物的基础上,因为将其中的x只替换为腿少的动物而减少的腿数。同理,m-an就是总腿数减假设全是腿少的动物时的腿数。

本题求解不难,关键是认清有解的条件为:鸡和兔的只数都是非负整数。

四、C语言源代码

#include

int main()

{

int a, b, n, m;

scanf("%d%d", &n, &m);

a = (4*n-m)/2;

b = n-a;

if(m % 2 == 1 || a < 0 || b < 0)

printf("No answer\n");

else

printf("%d %d\n", a, b);

return 0;

}

你可能感兴趣的:(信息学奥赛,算法)