洛谷--P2089烤鸡

题目背景
猪猪 Hanke 得到了一只鸡。

题目描述
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10种配料(芥末、孜然等),每种配料可以放 1到 3克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 nn ,请输出这 1010 种配料的所有搭配方案。

输入格式
一个正整数 n,表示美味程度。

输出格式
第一行,方案总数。

第二行至结束,10 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 0。

输入输出样例
输入
11
输出
10
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 2 1 1 1 1
1 1 1 1 2 1 1 1 1 1
1 1 1 2 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1
1 2 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1
说明/提示
对于 100%100% 的数据,n \leq 5000n≤5000。

思路:一开始我想从n出发,对n-10后的部分进行分配,这样能计算出方案数,但不容易输出每个方案,而且没有考虑美味度上界(30),错的离谱,,,
这是我最初的错误代码。

int main()
{
    //define variable and initialize
    int season[10]={1,1,1,1,1,1,1,1,1,1};
    int n,i,j;
    long long int res=0;//方案数
    //get data
    scanf("%d",&n);
    //calculate
    if(n==10)
        res=1;
    else if(n<10)
        res=0;
    else if(n>10)
    {
        n-=10;//得到10以外多出的部分
        res+=10;//多出的部分整体分配到一种调料中,10选1,共十种(error:没有考虑一种调料最多放三克)
        for(i=1;i<=n/2;i++)//不断分出一部分(分出1,2,3……)方案数即组合数(error:没有考虑一种调料最多放三克)
        {
            int tem=n;
            tem-=i;j=2;//分为j部分,一部分为tem,剩余部份全为i
            while(tem>0&&j<=10)
            {
            res+=f(10,j);//函数f计算组合数,10选j
            j++;
            tem-=i;
            }
        }
    }

    // output result
    printf("%d\n",res);
    return 0;
}

改正后:

搜到的大佬的答案,代码如下:

#include<cctype>
#include<cstdio>

using namespace std;

const int maxn = 13;

char ans[1000000 + 5];
char *anscur = ans;
int nums[maxn];                    // 当前调料 
int cnt = 0;                    // 方案数 

void printans(){
    int offset;
    for(int i = 0; i < 10; i++){
        sprintf(anscur, "%d %n", nums[i], &offset);//%n 作用:将输入的数据项数存入offset中
        anscur += offset;//使指针指向下一次输入的起始位 用%n就避免了使用strlen,降低时间复杂度
    }
    sprintf(anscur, "\n%n", &offset);
    anscur += offset;
}

void dfs(int cur, int left){    // 深搜过程 
    if(cur == 10 && !left){        // 已经搜到第10层,这个时候调料恰好加完 
        cnt++;                    // 方案数+1 
        printans();                // 将方案输出到字符串里面 
        return;
    } 
    int &i = nums[cur];            // 声明别名(引用) 
    for(i = 1; i <= 3; i++){
        if((10 - cur - 1) * 3 + i < left) continue;    // 剪枝。如果剩下的调料都加3克都不够,说明不可能 
        if((10 - cur - 1) + i > left) break;        // 剪枝。如果剩下的调料都加一克也超量,说明不可能 
        dfs(cur + 1, left - i); 
    }
}

int main(){
    int n;
    scanf("%d", &n);

    if(10 <= n && n <= 30) dfs(0, n);// 如果n不在[10, 30]范围内,说明不可能有解,跳过搜索 
    printf("%d\n%s", cnt, ans);        //输出答案 
}
//最终用时34ms,最长一个点10ms,快了差不多几十倍。

正解:深度搜索 剪枝操作和字符串存储,大大降低复杂度

el-footer是Element UI库中的一个组件,用于在页面底部添加一个固定的页脚。它的使用方式如下: ```html <template> <div> <el-header>Header</el-header> <el-main>Main Content</el-main> <el-footer>Footer</el-footer> </div> </template> ``` 在上面的例子中,el-header、el-main和el-footer分别代表页面的头部、主体和底部。el-footer会被固定在页面底部,无论页面内容的高度是多少。 如果你想让el-footer沉底,即当页面内容不足以撑满整个屏幕时,让el-footer始终保持在页面底部,可以使用CSS中的flex布局来实现。具体的代码如下: ```html <template> <div class="container"> <div class="content"> <!-- 页面内容 --> </div> <el-footer class="footer">Footer</el-footer> </div> </template> <style> .container { display: flex; flex-direction: column; min-height: 100vh; } .content { flex: 1; } .footer { margin-top: auto; } </style> ``` 上面的代码中,我们创建了一个flex容器(class为container),设置了它的`min-height`为`100vh`,确保容器至少占满整个屏幕高度。然后,将页面内容放在一个div(class为content)中,并设置其`flex`属性为1,让它占满剩余的空间。最后,将el-footer的`margin-top`属性设置为`auto`,使其自动填充剩余的空间,从而将el-footer沉底。 这样,无论页面内容的高度是多少,el-footer都会保持在页面底部。希望对你有帮助!如有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值