在《芈月传》第29集,黄歇在集市解决了一件“用整钱买整鸡”的难题:鸡翁五钱两只,鸡婆三钱两只,鸡雏一钱六只。顾客用五十整钱,要买正好一百只整鸡。要求每种鸡都要买到,并且鸡翁少买,鸡婆多买,鸡雏最多。问,分别买鸡翁,鸡婆,鸡雏多少只?
我在用C++代码编写程序解答这道题目时,重视了以下三个编程习惯。
1、不要重复编写同一个字面量,应该将其封装在变量之中。
2、不要编写相互存在算术逻辑关系的两个字面量,应该利用C++表达式体现二者之间的算术逻辑关系。
3、所有限制条件都应该利用C++表达式来实现,而不要 “ 事先用笔算出结果、再将结果硬编码到程序中 ” 。
完整思路详见《C++自学笔记(上册)面向过程》7.6.2节的示例2。这本书暂时还未出版,因此与该书有关的任何图片、表格、代码、文章(包括本篇)都谢绝转载。
程序如下。其中,cock是鸡翁,hen是鸡婆,chick是鸡雏,P代表价格Price,A代表数量Amount,M代表倍数Multiple。
// continueCockHenChick.cpp
#include <iostream> //cout, endl
using std::cout;
using std::endl;
int main()
{
const int cockP=5, henP=3, chickP=1, totalP=50; //单位鸡翁价、单位鸡婆价、单位鸡雏价、总价
const int cockA=2, henA=2, chickA=6, totalA=100; //单位鸡翁数、单位鸡婆数、单位鸡雏数、总数
int cockM=1, henM=1, chickM=1; //鸡翁的单位数、鸡婆的单位数、鸡雏的单位数
cout<<" If "<<cockP<<" yuan to buy "<<cockA<<" cocks,"<<endl<<
"and "<<henP<<" yuan to buy "<<henA<<" hens,"<<endl<<
"and "<<chickP<<" yuan to buy "<<chickA<<" chicks,"<<endl<<
" then"<<endl;
for(;(cockM*cockA<=totalA-henA-chickA)&& //总数至少含有一单位的鸡婆和鸡雏
(cockM*cockP<=totalP-henP-chickP); cockM++) //总价至少含有一单位的鸡婆和鸡雏
{
for(henM=1; (henM*henA<=totalA-cockA-chickA)&& //总数至少含有一单位的鸡翁和鸡雏
(henM*henP<=totalP-cockP-chickP); henM++)//总价至少含有一单位的鸡翁和鸡雏
{
for(chickM=1; (chickM*chickA<=totalA-cockA-henA)&& //总数至少含有一单位的鸡翁和鸡婆
(chickM*chickP<=totalP-cockP-henP); chickM++)
{ //总价至少含有一单位的鸡翁和鸡婆
if((cockM*cockP+henM*henP+chickM*chickP!=totalP)|| //如果三种鸡数之和不等于总数、
(cockM*cockA+henM*henA+chickM*chickA!=totalA)|| //或者三种鸡价之和不等于总价、
(cockM*cockA>=henM*henA)|| //或者鸡翁数不是最少、
(henM*henA>=chickM*chickA)) //或者鸡雏数不是最多,
continue; //则跳过下一条输出语句,继续穷举下一组数据
cout<<totalP<<" yuan to buy "<<cockM*cockA<<" cocks, "<<
henM*henA<<" hens and "<<chickM*chickA<<" chicks!"<<endl;
}
}
}
return 0;
}
执行结果截图:
因为遵守了前面提到的三个习惯,使该程序具有的最大优势是:以后在解决同类型问题时,维护工作量比较低。
例如,(1)假设鸡翁、鸡婆、鸡雏价格都翻倍了,并且总钱数也翻倍了,其它条件一样,结果会变成多少?
再例如,(2)假设鸡翁和鸡婆价格翻倍了,鸡雏价格跌了一半,并且总钱数翻倍了,其它条件一样,结果会变成多少?
在解决最后这两个同类型问题时,只需改变程序的哪些位置就能得出新结果呢?这,还是留作读者自行思考吧。
: