C语言----找零问题----程序优化
题目详情:
现有一元,两元,五元面额的纸币若干,给出任意的找零要求,给出每种找零方案,输出循环次数。
优化代码一:
代码优化内容:
利用num/5,num/2来进行判断,减少了找零超额的循 环次数。
同时,利用beak跳出循环,减少了最后的超额循环次数。
优化总结:减少得到答案后的无效循环。-----注意:这里是减少的是找到答案以后的无效循环。
代码二:
# include <stdio.h>
int main (void)
{
int num,i,j,k,count=0;//I,J,K,分别表示一元,二元,五元的硬币。
scanf("%d",&num);
for(k=0;k<=num/5;k++)
for(j=0;j<=num/2;j++)
{i=num-j*2-k*5;
count++;
if(num==i+5*k+2*j)
printf("%d %d %d\n",i,j,k);
}
printf("%d",count);
return 0;
}
优化分析:
(1)纸币找零面额先从5开始遍历,这样可以省去如图一的在不合格k,j中i的循环次数。
代码三:增加最小值判断------当我们从5开始遍历后,我们可以知道,每增加一张五元纸币,小面额纸币可以减少更多,我们可以应用一个最小值判断,当以后的循环(最外层循环)的纸币总数大于前面的纸币总的时候,我们可以不用循环了。
话题:(回归到1.2.5的找零问题,图式代码为修改验证思考代码)在这个代码的测试过程中,我们发现了一个有趣的事情,即程序循环的次数与最终的方案数相同,那么,这究竟是怎么一回事呢?
思考与解答:原来是因为在第二层循环中,这位同学更进一步利用了j2<=num-5k直接保证了,i小于零的情况不可能出现。而最小面额是一直接可以对缺少的项进行填充;而当最小面额是二是,就会有奇数带填充而无法填充的情况,使得最后循环次数与方案数不相同。
题外话
在本题最后,这位同学利用6.3.2的面额进行测试,而作者利用7.5.2,进行测试,这时,我们想到了一个问题,就是6.3.2可不可以遍历所有整数。
结果:我们只需要考虑互为质因数的两个找零,6可以删去,因为6可以由三个2代替,那么3使得一个数字成为一个奇数,二使得这个奇数可以成为大于这个奇数的任何奇数。我们只需要考虑最小的可找零奇数,1–不可,3—可以,所以,我们可以知道,这三种面额的纸币可以遍历2及其以上所有整数。