洛谷 P2089 烤鸡

原题目传送门

这道题目怎么说,完全就可以用枚举来解决问题。因为一共只有10种佐料,并且每一种佐料只最多加3克,最少加1克,那么我们就定义10个变量,分别来对应这10中配料。
当然,因为这道题目我们需要输出方案的总数,那么就是在枚举过程中,如果这些配料之和等于我们输入的数,那么1计数器++,输出计数器。
当然,再次进行一遍操作,就是为了输出每一个方案,那么同样,如果在枚举过程中这些配料之和等于我们输入的数,那么就把每一个变量对应输出出来就完事儿了。

上代码

第一个炒鸡大循环就是来数有多少种方案满足条件。
第二个炒鸡大循环就是来输出每个具体方案。
对这个题,这么多循环的时间完全够用。而且代码也非常优美,浅显易懂。(逃

#include <bits/stdc++.h>
using namespace std;
int ing_1,ing_2,ing_3,ing_4,ing_5; // 这里的ing表示配料(从1到10)
int ing_6,ing_7,ing_8,ing_9,ing_10;
int n,ans=0; // n作为我们输入的数,ans作为方案的总数。
int main(){
    scanf("%d",&n);
    for (ing_1=1;ing_1<=3;ing_1++){
        for (ing_2=1;ing_2<=3;ing_2++){
            for (ing_3=1;ing_3<=3;ing_3++){
                for (ing_4=1;ing_4<=3;ing_4++){
                    for (ing_5=1;ing_5<=3;ing_5++){
                        for (ing_6=1;ing_6<=3;ing_6++){
                            for (ing_7=1;ing_7<=3;ing_7++){
                                for (ing_8=1;ing_8<=3;ing_8++){
                                    for (ing_9=1;ing_9<=3;ing_9++){
                                        for (ing_10=1;ing_10<=3;ing_10++){
                                            if (ing_1+ing_2+ing_3+ing_4+ing_5+ing_6+ing_7+ing_8+ing_9+ing_10==n){
                                                ans++; // 如果满足条件就计数器++
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    printf("%d\n",ans);
    for (ing_1=1;ing_1<=3;ing_1++){
        for (ing_2=1;ing_2<=3;ing_2++){
            for (ing_3=1;ing_3<=3;ing_3++){
                for (ing_4=1;ing_4<=3;ing_4++){
                    for (ing_5=1;ing_5<=3;ing_5++){
                        for (ing_6=1;ing_6<=3;ing_6++){
                            for (ing_7=1;ing_7<=3;ing_7++){
                                for (ing_8=1;ing_8<=3;ing_8++){
                                    for (ing_9=1;ing_9<=3;ing_9++){
                                        for (ing_10=1;ing_10<=3;ing_10++){
                                            if (ing_1+ing_2+ing_3+ing_4+ing_5+ing_6+ing_7+ing_8+ing_9+ing_10==n){
                                                printf("%d %d %d %d %d %d %d %d %d %d\n",ing_1,ing_2,ing_3,ing_4,ing_5,ing_6,ing_7,ing_8,ing_9,ing_10); // 输出每一一个方案,每个数之间一定要加空格
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    system("pause");
    return 0;
}

关于正解……
上面那个解法纯属是因为看这道题目数据范围比较小(只有10种配料,而且每一种配料最多3克),那么我们实际上可以把上面的过程给简化一下,就用递归吧~(TMD这个61键键盘太难用了)

#include <bits/stdc++.h>
using namespace std;
int n,type=0,res[10000][10],ing[10]; // 这里n是输入的数,type是调料的种类,res用来存储结果,ing是10种调料
void search(int total,int num){
    if (num==10){
        if (total==n) {
            for (int i=0;i<10;i++) res[type][i]=ing[i]; // 如果符合条件,就放入二维表种存储
            type++;
        }
    }
    else if (total>=n) return;
    else{
        for (int i=1;i<=3;i++){
            ing[num]=i;
            search(total+i,num+1);
        }
    }
}
int main(){
    scanf("%d",&n);
    search(0,0);
    cout<<type<<endl;
    for (int i=0;i<type;i++){
        for (int j=0;j<10;j++) printf("%d ",res[i][j]);
        printf("\n");
    }
    system("pause");
    return 0;
}

这个代码完全就是把上面的10连循环的简化版,在我们的search()函数中我们已经用递归的方式简化了我们的枚举操作,并且直接把答案存储在了二维表里面。当然,这种简化可能并没有上面的炒鸡大代码来的直观,但是对于部分强迫症群体对于代码的长度、宽度等有奇特要求的人,我们也管不着![](https://img2020.cnblogs.com/blog/2528810/202112/2528810-20211229172724439-116178021.png


最后,关于正解。这道题完全可以使用搜索+回溯法来实现。

AC记录

图片可能挂了

点个赞再走呗!

posted @ 2021-12-29 09:17  煎饼Li  阅读(86)  评论(0编辑  收藏  举报