第二屆藍橋杯C/C++組第九題 購物(遞歸)

公司發了某商店的購物券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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章