中国古代数学家张丘在他的《算经》中提出了一个著名的"百钱百鸡问题":一只公鸡值5钱,一只母鸡值3钱,三只小鸡值1钱,现在要用百钱买百鸡,请问公鸡、母鸡、小鸡各多少只?
问题分析分别假设公鸡、母鸡、小鸡的数量为cock、hen、chicken,初始值为0,如果100钱全部买成公鸡,最多20只,全部买成母鸡最多33只,全部买成小鸡最多300只,由此确定三个变量的取值范围。可以采用三层for循环实现,当满足cock+hen+chicken=100且花费的钱正好100时满足要求。(注意:C语言中两个整数相除得到的结果仍为整数,“/”两边有一个数为float型得到的结果即为float型)
代码#include
int main(){
int cock,hen,chicken;
for(cock=0;cock<=20;cock++) //外层循环控制公鸡数量取值范围0-20
for(hen=0;hen<=33;hen++) //内层循环控制母鸡的数量取值范围0-33
for(chicken=0;chicken<=100;chicken++){ // 内层循环控制小鸡数量取值范围0-100
if((cock+hen+chicken == 100) && (5*cock + 3*hen + chicken/3.0==100))
printf("cock=%d,hen=%d,chicken=%d\n",cock,hen,chicken);
}
}
输出示例
代码分析
上述算法需要穷举21*34*101=72114次,效率太低。对于这类求解不定方程的问题,各层循环的控制变量直接与方程的未知数相关,且采用对未知数的取值范围穷举和组合的方法可以得到全部的解。对于本题,当公鸡的数量确定后,小鸡的数量就固定为100-cock-chicken,无须再进行穷举了,此时约束条件只有一个:5*cock+3*hen+chicken/3.0=100,这样我们利用两重循环即可实现。
改进后的代码如下:
#include
int main() {
int cock,hen,chicken;
for(cock=0; cock<=20; cock++) //外层循环控制公鸡数量取值范围0-20
for(hen=0; hen<=33; hen++) { //内层循环控制母鸡的数量取值范围0-33
chicken=100-cock-hen;
if(5*cock + 3*hen + chicken/3.0==100)//验证解的合理性
printf("cock=%d,hen=%d,chicken=%d\n",cock,hen,chicken);
}
}
改进后的代码只需要尝试21*34=714次,进一步提高了算法的效率。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)