C语言经典问题——兑换硬币

兑换硬币问题

  兑换硬币问题是C语言的一个经典问题。题目如下:

现有一张1元纸币,欲将其兑换为1分、2分、5分硬币共60枚,请列出所有兑换方案。

  我们可以利用分支和循环来解决这个问题。

最简单的方法——三重循环法

  最“无脑”也是最容易想到的方法是利用三重循环。其代码如下所示:

#include <stdio.h>
int main (void)
{
	int i = 0; 
	int one, two, five; 
	for (one = 0; one <= 60; one++)
	{
		for (two = 0; two <= 50; two++)
		{
			for (five = 0; five <= 20; five++)
			{
				if ((one * 1 + two * 2 + five * 5 == 100) && (one + two + five == 60))
				{
					i++; 
					printf ("兑换方案%2d:1分硬币%2d枚,2分硬币%2d枚,5分硬币%2d枚\n", i, one, two, five); 
				}
			}
		}
	}
	printf ("共有%d种兑换方案\n", i); 
	return 0; 
}

  输出结果如下:

兑换方案 1:1分硬币20枚,2分硬币40枚,5分硬币 0枚
兑换方案 2:1分硬币23枚,2分硬币36枚,5分硬币 1枚
兑换方案 3:1分硬币26枚,2分硬币32枚,5分硬币 2枚
兑换方案 4:1分硬币29枚,2分硬币28枚,5分硬币 3枚
兑换方案 5:1分硬币32枚,2分硬币24枚,5分硬币 4枚
兑换方案 6:1分硬币35枚,2分硬币20枚,5分硬币 5枚
兑换方案 7:1分硬币38枚,2分硬币16枚,5分硬币 6枚
兑换方案 8:1分硬币41枚,2分硬币12枚,5分硬币 7枚
兑换方案 9:1分硬币44枚,2分硬币 8枚,5分硬币 8枚
兑换方案10:1分硬币47枚,2分硬币 4枚,5分硬币 9枚
兑换方案11:1分硬币50枚,2分硬币 0枚,5分硬币10枚
共有11种兑换方案

稍加改进——双重循环法

  通过分析上面的程序,我们可以发现,通过利用变量one,two和five之间的关系,即one+two+five=60,我们可以减少一层循环,从而达到代码的优化。改进后的代码如下:

#include <stdio.h>
int main(void)
{
	int i = 0;
	int one, two, five;
	for (five = 0; five < 20; five++)
	{
		for (two = 0; two < 50; two++)
		{
			one = 60 - two - five;
			if (one + two * 2 + five * 5 == 100)
			{
				i++;
				printf ("兑换方案%2d:1分硬币%2d枚,2分硬币%2d枚,5分硬币%2d枚\n", i, one, two, five);
			}
		}
	}
	printf ("共有%d种兑换方案\n", i); 
	return 0; 
}

  输出结果如下:

兑换方案 1:1分硬币20枚,2分硬币40枚,5分硬币 0枚
兑换方案 2:1分硬币23枚,2分硬币36枚,5分硬币 1枚
兑换方案 3:1分硬币26枚,2分硬币32枚,5分硬币 2枚
兑换方案 4:1分硬币29枚,2分硬币28枚,5分硬币 3枚
兑换方案 5:1分硬币32枚,2分硬币24枚,5分硬币 4枚
兑换方案 6:1分硬币35枚,2分硬币20枚,5分硬币 5枚
兑换方案 7:1分硬币38枚,2分硬币16枚,5分硬币 6枚
兑换方案 8:1分硬币41枚,2分硬币12枚,5分硬币 7枚
兑换方案 9:1分硬币44枚,2分硬币 8枚,5分硬币 8枚
兑换方案10:1分硬币47枚,2分硬币 4枚,5分硬币 9枚
兑换方案11:1分硬币50枚,2分硬币 0枚,5分硬币10枚
共有11种兑换方案

  我们得到了相同的输出结果,可见这种想法是可行的。

最优方法——单重循环法

  实际上,这道题只用单重循环也是可以解决的。
  我们再次对变量one,two和five之间的关系进行分析,不难得出以下两个关系式:

one + two + five = 60
one + two × 2 + five × 5 = 100

  整理之后,得:

two + five × 4 = 40,即 two = 40 - five × 4
five ≤ 10

  根据上面的分析,我们可以再次优化代码,如下所示:

#include <stdio.h>
int main(void)
{
	int i = 0;
	int one, two, five;
	for (five = 0; five <= 10; five++)
	{
		two = 40 - 4 * five;
		one = 60 - two - five;
		if (one + two * 2 + five * 5 == 100)
		{
			i++;
			printf ("兑换方案%2d:1分硬币%2d枚,2分硬币%2d枚,5分硬币%2d枚\n", i, one, two, five);
		}
	}
	printf ("共有%d种兑换方案\n", i); 
	return 0;
}

  输出结果依旧和上面的两个程序相同:

兑换方案 1:1分硬币20枚,2分硬币40枚,5分硬币 0枚
兑换方案 2:1分硬币23枚,2分硬币36枚,5分硬币 1枚
兑换方案 3:1分硬币26枚,2分硬币32枚,5分硬币 2枚
兑换方案 4:1分硬币29枚,2分硬币28枚,5分硬币 3枚
兑换方案 5:1分硬币32枚,2分硬币24枚,5分硬币 4枚
兑换方案 6:1分硬币35枚,2分硬币20枚,5分硬币 5枚
兑换方案 7:1分硬币38枚,2分硬币16枚,5分硬币 6枚
兑换方案 8:1分硬币41枚,2分硬币12枚,5分硬币 7枚
兑换方案 9:1分硬币44枚,2分硬币 8枚,5分硬币 8枚
兑换方案10:1分硬币47枚,2分硬币 4枚,5分硬币 9枚
兑换方案11:1分硬币50枚,2分硬币 0枚,5分硬币10枚
共有11种兑换方案
发布了21 篇原创文章 · 获赞 6 · 访问量 1664

猜你喜欢

转载自blog.csdn.net/qq_45554010/article/details/103501842