题目来源:《算法竞赛入门经典》例题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只。
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<stdio.h>
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;
}