题目:
百鸡问题是北魏数学家张丘建在其著作《张丘建算经》中提出的一个世界著名的不定方程问题:“今有鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。凡百钱买鸡百只,问鸡翁母雏各几何。”
百钱百鸡问题的白话版:100元钱买100只鸡,公鸡5元1只,母鸡3元1只,小鸡1元3只。问公鸡、母鸡、小鸡各多少只(某种鸡可以为0只)?
百钱百鸡的结果如输出样例所示。
现在把100改为n,即n元钱买n只鸡,各种鸡价格不变,结果又如何呢?
测试数据保证至少存在一组解。
输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n(100<=n<=1000)。
输出格式:
对于每组测试,按公鸡、母鸡、小鸡的数量(按公鸡数从小到大的顺序)逐行输出各种买法(每行数据之间空一个空格)。
输入样例:
100
输出样例:
0 25 75
4 18 78
8 11 81
12 4 84
解题思路:
设公鸡、母鸡和小鸡的数量分别为 cock、hen、chick,则可以列出以下三个方程:
(1) cock + hen + chick = 100(总数为100只)
(2) 5cock + 3hen + chick/3 = 100(总价为100元)
(3) chick是3的倍数(钱每增加一元,小鸡的数量多三只)
这个算法会遍历所有可能的组合,找到符合条件的解。在实际编程中,这种暴力搜索的方法虽然不是最高效的,但对于这个问题规模较小的情况下是可行的。
如要减少时间复杂度,可以从循环的结束条件入手。假设全部的钱都拿来买一种类型的鸡,那该类型鸡的循环最大次数为鸡的数量。如100全部买cock,cock 5元一只,100可以买cock的最大数量为100/5 = 20只,所以cock循环的结束条件可简化为 cock <= n/5 。
代码(C语言):
#include <stdio.h>
int main()
{
int n;
// cock:公鸡 hen:母鸡 chick:小鸡
while(scanf("%d",&n) != EOF) //!= EOF表示处理到文件尾
{
//cock<=n/5:假设全部买公鸡的情况,为了解决运行超时问题
for(int cock=0; cock<=n/5; cock++)
{
for(int hen=0; hen<=n; hen++)
{
//chick+=3等同于chick=chick+3 表示小鸡1元3只,每花一块钱增加的小鸡数量+3
for(int chick=0; chick<=n; chick+=3)
{
//当钱的数量和鸡的数量都等于n时满足题目
if((cock*5 + hen*3 + chick/3 == n) && (cock+hen+chick == n))
{
printf("%d %d %d\n", cock, hen, chick);
}
}
}
}
}
return 0;
}
该题形同N马N担问题(PTA 7-136 n马n担问题 ), 搬砖问题(PTA 7-145 搬砖),算法与解题思路高度相似。