第二屆藍橋杯C/C++組第九題 購物(遞迴)
阿新 • • 發佈:2019-02-18
公司發了某商店的購物券1000元,限定只能購買店中的m種商品。每種商品的價格分別為m1,m2,…,要求程式列出所有的正好能消費完該購物券的不同購物方法。
程式輸入:
第一行是一個整數m,代表可購買的商品的種類數。
接下來是m個整數,每個1行,分別代表這m種商品的單價。
程式輸出:
第一行是一個整數,表示共有多少種方案
第二行開始,每種方案佔1行,表示對每種商品購買的數量,中間用空格分隔。
例如:
輸入:
2
200
300
則應輸出:
2
2 2
5 0
輸入:
2
500
800
則應輸出:
1
2 0
要求考生把所有函式寫在一個檔案中。除錯好後,存入與考生資料夾下對應題號的“解答.txt”中即可。相關的工程檔案不要拷入。
對於程式設計題目,要求選手給出的解答完全符合ANSI C標準,不能使用c++特性;不能使用諸如繪圖、中斷呼叫等硬體相關或作業系統相關的API。
遞迴思路,具體見程式碼註解。
#include<stdio.h> #include<string.h> int m;//物品數 int p[100];//價格 int ans[100][100];//ans[i][j]表示第i個方案中第j個物品被選數 int num[100];//num[i]表示第i件物品被選的個數 int cas=0;//方案數 int money=0;//花的錢 void buy(int n)//n表示當前搜尋到的物品編號 { if(money>1000||n>=m)//當花的錢超過預算或者所有的物品都已遍歷過了,不再繼續搜尋下去 return ; if(money==1000)//當花的錢正好為1000,滿足要求 { for(int i=0; i<m; i++) ans[cas][i]=num[i]; cas++; return ; } num[n]++;//選該物品 money+=p[n]; buy(n);//可以繼續選該物品 num[n]--;//不選該物品,前面加的要減去 money-=p[n];//錢也相應的減 buy(n+1);//選下一個物品 } int main() { scanf("%d",&m); for(int i=0; i<m; i++) scanf("%d",&p[i]); memset(num,0,sizeof(num)); buy(0); printf("%d\n",cas); for(int i=0; i<cas; i++) { for(int j=0; j<m; j++) printf("%d ",ans[i][j]); printf("\n"); } return 0; }