买书问题

    题目:在节假日的时候,书店一般都会做促销活动。由于《哈利波特》系列相当畅销,店长决定通过促销活动来回馈读者。在销售《哈利波特》平装本系列中,一共有五卷,用编号0,1,2,3,4来表示。假设每一卷单独销售均需要8欧元,如果读者一次购买不同的两卷,就可以扣除5%的费用,三卷则更多。假设具体折扣的情况如下:

    本数        折扣

    2            5%

    3            10%

    4            20%

    5            25%

    在一份订单中,根据购买的卷数以及本数,就会出现可以应用不同折扣规则的情况。但是,一本书只会应用一个折扣。比如,读者一共买了两本卷一,一本卷二。那么,可以享受5%的折扣。另外一本卷一则不能享受折扣。如果有多种折扣,希望能够计算出的总额尽可能的低。

    要求根据这样的需求,设计出算法,能够计算出读者所购买一批书的最低价格。

 

    设计思想:

    利用归纳演绎的方法求解一般规律。根据题目提供的信息可知,当购买1-5本时,选择不同的卷号则可以获得的折扣最大,当购买的本数在6-10之间时,则需要通过分解的方式来计算最大的折扣。通过计算可知,购买的本数为6时,采用5+1的分解方式折扣最大,购买本数为7时,采用5+2的分解方式折扣最大,够买本数为8时,采用4+4的分解方式折扣最大,购买本数为9时,采用5+4的分解方式折扣最大,当购买本数为10时,采用5+5的分解方式折扣最大。由此可以总结出一般规律,当购买的本数在1—10之间时,分别对应10种不同的情况,当购买的本数大于十时,则可以通过除以10求余的方式将其转化为10以内的情况,最低总价只需再加上X倍的购买10本时的最低价格(X为除以10得到的商)。

 

    程序源代码如下:

//买书问题
//Hailin Song  2016-06-03

#include<iostream>
using namespace std;

int main()
{
	int booknumber;                      //所需购买的本数
	cout << "请输入需要购买多少本书:";
	cin >> booknumber;

	while (booknumber<1)                 //若输入错误则重新输入
	{
		cout << "输入错误,请重新输入:";
		cin >> booknumber;
	}

	if (booknumber < 11)                 //购买的本数为1-10的情况
	{
		switch (booknumber)
		{
		case 1:
			cout << "购买方案:买5卷中的任意一卷,总价格为8欧元,没有折扣!";
			break;
		case 2:
			cout << "购买方案:买5卷中的任意不同的两卷,最低总价为15.2欧元!";
			break;
		case 3:
			cout << "购买方案:买5卷中的任意不同的三卷,最低总价为21.6欧元!";
			break;
		case 4:
			cout << "购买方案:买5卷中的任意不同的四卷,最低总价为25.6欧元!";
			break;
		case 5:
			cout << "购买方案:购买不同的五卷,最低总价为30欧元!";
			break;
		case 6:
			cout << "购买方案:购买不同的五卷,再从中任意挑选一卷,最低总价为38欧元!";
			break;
		case 7:
			cout << "购买方案:购买不同的五卷,再从中挑选不同的两卷,最低总价为45.2欧元!";
			break;
		case 8:
			cout << "购买方案:购买两套4本不同卷号的书,最低总价为51.2欧元!";
			break;
		case 9:
			cout << "购买方案:购买一套完整的五卷,再从五卷中挑选4本不同的卷,最低总价为55.6欧元!";
			break;
		case 10:
			cout << "购买方案:购买两套完整的五卷,最低总价为60元!";
			break;
		}
	}
	else
	{
		int booktao = booknumber / 10;               //购买本数除以10得到的商
		int bookyu = booknumber % 10;                //购买本数除以10得到的余数
		switch (bookyu)
		{
		case 0:
			cout << "购买方案:购买" << booktao * 2 << "套完整的五卷,最低总价为!" << 60 * booktao << "欧元!";
			break;
		case 1:
			cout << "购买方案:购买" << booktao*2 << "套完整的五卷,再任意挑选一卷,最低总价为" << 60 * booktao + 8 << "欧元!";
			break;
		case 2:
			cout << "购买方案:购买" << booktao*2 << "套完整的五卷,再任意挑选不同的两卷,最低总价为" << 60 * booktao + 15.2 << "欧元!";
			break;
		case 3:
			cout << "购买方案:购买" << booktao*2 << "套完整的五卷,再任意挑选不同的三卷,最低总价为" << 60 * booktao + 21.6 << "欧元!";
			break;
		case 4:
			cout << "购买方案:购买" << booktao*2 << "套完整的五卷,再任意挑选不同的四卷,最低总价为" << 60 * booktao + 25.6 << "欧元!";
			break;
		case 5:
			cout << "购买方案:购买" << booktao*2+1 << "套完整的五卷,最低总价为" << 60 * booktao+30 << "欧元!";
			break;
		case 6:
			cout << "购买方案:购买" << booktao*2+1 << "套完整的五卷,再任意挑选一卷,最低总价为" << 60 * booktao + 38 << "欧元!";
			break;
		case 7:
			cout << "购买方案:购买" << booktao*2+1 << "套完整的五卷,再任意挑选不同的两卷,最低总价为" << 60 * booktao + 45.2 << "欧元!";
			break;
		case 8:
			cout << "购买方案:购买" << booktao*2 << "套完整的五卷,再购买两套4本不同的卷号,最低总价为!" << 60 * booktao + 51.2 << "欧元!";
			break;
		case 9:
			cout << "购买方案:购买" << booktao*2+1 << "套完整的五卷,再任意挑选不同的四卷,最低总价为!" << 60 * booktao + 55.6 << "欧元!";
			break;
		}
	}

	return 0;
}

  

    测试结果截图:

 

   个人总结:

    买书问题是《编程之美》中的一个经典案例,老师上课时给我们展示出题目后,我的第一个感觉就是懵,读不懂题目的意识,在老师的引导下,开始一步步的深入分析题目。老师给我们的引导是采用演绎归纳的方法,即通过计算特殊的情况找出一般的规律。通过这种方式,我们找出了1-10以后的各种情况,对于超出十的情况则可以通过求余的方式转化为十以内的情况。这种方法确实很好用,用这种方法去解决问题也非常简单易懂。

    在《编程之美》这本书中,对于这个问题给出了两种不同的解法,第一种解法采用了数学公式的算法,不过这种算法时间复杂度和空间复杂度都比较高,第二种算法是贪心策略,其实就是上述的演绎规范方法,但是对于《编程之美》上的介绍没有看懂,以后有时间的话再进行深入的研究吧。

   

原文地址:https://www.cnblogs.com/hulidanxiang/p/5561038.html