【题解】【枚举】——烤鸡
烤鸡
题目背景
猪猪 Hanke 得到了一只鸡。
题目描述
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10 10 10 种配料(芥末、孜然等),每种配料可以放 1 1 1 到 3 3 3 克,任意烤鸡的美味程度为所有配料质量之和。
现在, Hanke 想要知道,如果给你一个美味程度 n n n ,请输出这 10 10 10 种配料的所有搭配方案。
输入格式
一个正整数 n n n,表示美味程度。
输出格式
第一行,方案总数。
第二行至结束, 10 10 10 个数,表示每种配料所放的质量,按字典序排列。
如果没有符合要求的方法,就只要在第一行输出一个 0 0 0。
输入输出样例
输入 #1
11
输出 #1
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\% 100% 的数据, n ≤ 5000 n \leq 5000 n≤5000。
解法1.直接枚举
1.1.题意解析
使用最简单粗暴的枚举就能解决。
这里有一个节省时间的小技巧:使用宏函数。
话不多说,直接看代码示例。
1.2.AC代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i) for(int i=1;i<=3;i++)//定义宏函数
int main()
{
int n,ans=0;
scanf("%d",&n);
rep(a)rep(b)rep(c)rep(d)rep(e)rep(f)rep(g)//使用宏函数
rep(h)rep(i)rep(j)
if(a+b+c+d+e+f+g+h+i+j==n)
ans++;
if(ans==0)
{
printf("0");
return 0;
}
printf("%d\n",ans);
rep(a)rep(b)rep(c)rep(d)rep(e)rep(f)rep(g)
rep(h)rep(i)rep(j)
if(a+b+c+d+e+f+g+h+i+j==n)
printf("%d %d %d %d %d %d %d %d %d %d\n",a,b,c,d,e,f,g,h,i,j);
return 0;
}
解法2.剪枝优化
2.1.题意解析
当然,虽然上面的代码已经可以通过此题了,但为了拓宽眼界,还是给大家提供一种剪枝思路。
我们可以发现,每个变量在枚举时,都有必要留下充足的空间给后面的变量。比如a
,后面的九个变量加起来最多需要27
,所以a
的初值就可以设成n-27
,b
也同理,它不仅要给后面的八个变量留24
,还要给a
留下空间。其它也同理。
至于上限,还是拿a
举例。a
后面的九个变量加起来最少需要9
,所以a
的上限就是n-9
,其它同理。
注意:此处rep
的定义需要改成这样:
#define rep(i,a,b) for(int i=max(1,a);i<=min(3,b);i++)
想一想,为什么?
最后,我们可以使用一个数组li
把答案缓存下来,避免重复计算。
2.2.AC代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=max(1,a);i<=min(3,b);i++)
int n,ans,li[5010][10];
int main()
{
cin>>n;
rep(a,n-27,n-9)
rep(b,n-24-a,n-8-a)
rep(c,n-21-a-b,n-7-a-b)
rep(d,n-18-a-b-c,n-6-a-b-c)
rep(e,n-15-a-b-c-d,n-5-a-b-c-d)
rep(f,n-12-a-b-c-d-e,n-4-a-b-c-d-e)
rep(g,n-9-a-b-c-d-e-f,n-3-a-b-c-d-e-f)
rep(h,n-6-a-b-c-d-e-f-g,n-2-a-b-c-d-e-f-g)
rep(i,n-3-a-b-c-d-e-f-g-h,n-1-a-b-c-d-e-f-g-h)
rep(j,n-a-b-c-d-e-f-g-h-i,n-a-b-c-d-e-f-g-h-i)
{
li[ans][0]=a;li[ans][1]=b;li[ans][2]=c;li[ans][3]=d;
li[ans][4]=e;li[ans][5]=f;li[ans][6]=g;li[ans][7]=h;
li[ans][8]=i;li[ans][9]=j;
ans++;
}
cout<<ans<<endl;
for(int i=0;i<ans;i++)
{
for(int j=0;j<10;j++)
cout<<li[i][j]<<" ";
puts("");
}
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育