題目:在節假日的時候,書店一般都會做促銷活動。由于《哈利波特》系列相當暢銷,店長決定通過促銷活動來回饋讀者。在銷售《哈利波特》平裝本系列中,一共有五卷,用編号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以後的各種情況,對于超出十的情況則可以通過求餘的方式轉化為十以内的情況。這種方法确實很好用,用這種方法去解決問題也非常簡單易懂。
在《程式設計之美》這本書中,對于這個問題給出了兩種不同的解法,第一種解法采用了數學公式的算法,不過這種算法時間複雜度和空間複雜度都比較高,第二種算法是貪心政策,其實就是上述的演繹規範方法,但是對于《程式設計之美》上的介紹沒有看懂,以後有時間的話再進行深入的研究吧。