PTA习题4-5 换硬币 (20 分)——易犯错误以及思路分享

目录

综述:

题目:

输入格式:

输出格式:

输入样例:

输出样例:

正确代码:

 问题1: 

        解决方法:

问题2:

        解决办法:


 

综述:

        换硬币这个题在编写时思路较简单,把每一种情况列出来,符合条件的进行打印即可,但是这个换硬币题也有非常容易犯的错误,也困扰了我挺长时间,这次博客分享一下这些问题。本题目我在编写的时候遇到两个问题:

        1:结果正确能罗列出所有情况,但是上传PTA检测只是部分正确。

        2:程序运行时间有点长如何进行优化问题

题目:

        将一笔零钱换成5分、2分和1分的硬币,要求每种硬币至少有一枚,有几种不同的换法?

输入格式:

        输入在一行中给出待换的零钱数额x∈(8,100)。

输出格式:

        要求按5分、2分和1分硬币的数量依次从大到小的顺序,输出各种换法。每行输出一种换法,格式为:“fen5:5分硬币数量, fen2:2分硬币数量, fen1:1分硬币数量, total:硬币总数量”。最后一行输出“count = 换法个数”。

输入样例:

13

输出样例:

fen5:2, fen2:1, fen1:1, total:4

fen5:1, fen2:3, fen1:2, total:6

fen5:1, fen2:2, fen1:4, total:7

fen5:1, fen2:1, fen1:6, total:8

count = 4

正确代码:

        先附上正确代码,在下文谈论一下易犯错误,与程序优化的思路。

#include 
int main()
{
	int x = 0;
	scanf("%d", &x);
	int count = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	for (i = (x/5); i >= 1; i--)
		{
			for (j = (x/2); j >= 1; j--)
			{
				for (k = x; k >= 1; k--)
				{
					if (i * 5 + j * 2 + k * 1 == x)
					{
						printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n", i, j, k, i + j + k);
						count++;
					}
				}
			}
		}
		printf("count = %d", count);
	
	
	return 0;
}

 问题1: 

        在编写这段代码时,大家都容易想出来枚举的办法,但是我相信应该有不少同学只能得到4分,部分正确,原因是大家有可能忽略一句话:“要求按5分、2分和1分硬币的数量依次从大到小的顺序,输出各种换法。” 我反正是在做这个题的时候忽略了这个问题,不知道刷过这道题的同学会不会忽略,或者没忽略但是不知道怎么解决这个问题。

        解决方法:

        题目要求硬币数量从小到大排列,我们面对的问题就是如何使得先进行打印的硬币数量是最少的,那么如何使得硬币的数量最少呢?答案是币值越大的硬币数量让他越多,知道这一点之后,这个题的思路就真正明确了。具体做法可以看一下上文程序,从大币值数量多开始遍历,循环变量依次递减即可,这样最后打印的硬币数量便可以从小到大打印。

问题2:

        我在写这个代码的时候 i j k三个循环变量都是循环了x次,不知道有没有小伙伴也是这样干的,这种写法虽然没什么问题,但是会白白的多遍历很多次,如果你输入一个较大的数,比如说输入100,那么1分钱会循环100次,2分钱循环100次,5分钱也循环100次,这显然是非常不合常理的,因为2分钱和5分钱不可能有100个,这个程序的运行会变慢,有兴趣的可以尝试尝试。

        解决办法:

        这个优化方法也容易想,同样以输入100为例,100分钱,最多50个2分,最多20个5分,其实就是 x/i  的关系,具体程序如上,这样设置遍历条件之后会减少很多的遍历次数,程序运行的效率也会提升很多。

你可能感兴趣的:(PTA刷题,c语言)