• P2089 烤鸡


    题目传送门

    一、无脑大循环

    #include<bits/stdc++.h>
    
    using namespace std;
    vector<string> v1;
    
    int main() {
        int a, b, c, d, e, f, g, h, i, j, k, l = 0;
        cin >> k;
    
        for (a = 1; a <= 3; a++)
            for (b = 1; b <= 3; b++)
                for (c = 1; c <= 3; c++)
                    for (d = 1; d <= 3; d++)
                        for (e = 1; e <= 3; e++)
                            for (f = 1; f <= 3; f++)
                                for (g = 1; g <= 3; g++)
                                    for (h = 1; h <= 3; h++)
                                        for (i = 1; i <= 3; i++)
                                            for (j = 1; j <= 3; j++)
                                                if (a + b + c + d + e + f + g + h + i + j == k)
                                                    v1.push_back(to_string(a) + " " +
                                                                 to_string(b) + " " +
                                                                 to_string(c) + " " +
                                                                 to_string(d) + " " +
                                                                 to_string(e) + " " +
                                                                 to_string(f) + " " +
                                                                 to_string(g) + " " +
                                                                 to_string(h) + " " +
                                                                 to_string(i) + " " +
                                                                 to_string(j));
        cout << v1.size() << endl;
        for (int i = 0; i < v1.size(); i++)
            cout << v1[i] << endl;
        return 0;
    }
    

    二、深度优先搜索

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 100010; 
    //方案数量,预计,注意,此处可不是n的数据上限,而是可能的方案数量,尽量开大防止出错,黄海就因为开小了挂掉!
    const int M = 20;    //配料的数量,本题目是10,为了开大一点数组,加了10
    
    int a[N][M]; //保存所有可行的方案,描述,第i种方案,放过二维的第一个格子0,第二个格子1表示i种方案中第一个配料用多少克
    int path[M]; //记录当前正在计算的方案.本题经验,数组开小了,会出错n值错乱的诡异问题!!!!描述当前方案每一种配料用多少克
    /**
     C++语言中数组越界访问系统不会给出任何的提示,程序员可以超出数组边界进行读/写从而造成内存的混乱,
     而这种错误对初学者来说是很容易出现的、而又偏偏是很难调试的,因为系统不会给出错误的提示,所以就这样使用数组是不安全的。
     */
    
    /**
     对比暴力无脑大模拟,dfs的使用范围更广,很好理解,比如我们不知道要多少轮,轮次数需要输入进来,我们就没有办法预先控制循环的层数,
     而dfs天生就是可以处理不定层数的!
     */
    int n, cnt;  //美味值,可行方案数量
    
    /**
     * 假设我们在面临一种通用的场景,也就是通常说的“一般性场景”
     * (1)我们正在准备放入第step件调料,目前的情况是没放此种调料之前的美味值是sum
     * (2)第step件调料,我们可以选择放入1,2,3三种数量,需要用循环把这些都尝试一遍。
     * (3)如果我们选择完了数量i之后,我们需要继续向下一种调料出发,但情况已经发生了变化,变成处理第
     * step+1件调料,同时总和也变成了sum+i
     * (4)当处理完第10件调料后,也就是step=9(因为step是从0开始的)时,再向下就是递归出口,在这里判断是不是一组可行解。
     */
    //step为第几种调料,sum目前的配料之和
    void dfs(int step, int sum) {
        if (step == 11) {                                           //当10种调料都分析完了
            //如果配料之和等于输入值;
            //使用memcpy更简单,参数:目标数组,源数组,长度
            if (sum == n)memcpy(a[cnt++], path, sizeof path);
            //不管等不等,都需要返回了,递归的出口
            return;
        }
        //在当前step下,就是在讨论某一种调料时,面临三种选择,1,2,3
        for (int i = 1; i <= 3; i++) {
            path[step] = i;                           //第step种调料的配料为i
            dfs(step + 1, sum + i);          //递归,对下一种调料做同样的分析
        }
    }
    
    
    int main() {
        cin >> n;
    
        //从第1步开始,目前总和是0
        dfs(1, 0);
    
        //输出方案个数
        cout << cnt << endl;
        //再输出具体的方案
        if (cnt > 0) {
            for (int i = 0; i < cnt; i++) {
                for (int j = 1; j <= 10; j++)
                    cout << a[i][j] << " ";
                cout << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    彻底弄懂flex布局
    剖析Vue原理&实现双向绑定MVVM
    【Mysql进阶-3】大量实例悟透EXPLAIN与慢查询
    mysql 排序
    从ReentrantLock的实现看AQS的原理及应用
    Java面试之Synchronized解析
    基于vue-cli搭建vue项目开发环境
    在win环境下使用yarn安装 vue-cli
    优化器追踪示例
    MySQL常见的七种锁详细介绍
  • 原文地址:https://www.cnblogs.com/littlehb/p/15593612.html
Copyright © 2020-2023  润新知