题目
猪猪Hanke特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke吃鸡很特别,为什么特别呢?因为他有10种配料(芥末、孜然等),每种配料可以放1到3克,任意烤鸡的美味程度为所有配料质量之和。
现在, Hanke想要知道,如果给你一个美味程度n ,请输出这10种配料的所有搭配方案。
输入输出格式
输入格式
一个正整数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
代码1
这个题目美味程度最多只能达到3*10=30,至少是10。可以直接使用10层for循环,再加一个if判断,就能找到符合条件的情况。题目中字典序输出的意思就是前面的数越小,这个方案就排在前面。因为10层for循环蕴含了这一性质,所以字典序对解法没有影响。
这里使用宏的另外一种用法:构造语句。写下rep(a,1,3)时,编译器会自动在代码中把它替换成for(int a=1;a<=3;a++)。但要注意的是,宏定义只会做简单的字符串替换。如果定义了#define prod(a,b) a*b,然后又写了prod(a+b,c),编译器将会把它理解成a+b*c,并非想要的(a+b)*c。一个解决方案是定义宏时勤加括号,如#define prod(a,b) (a)*(b),这样就可以避免出现运算优先级的bug。
#include<iostream>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
int main(){
int n,ans=0,cnt=10;
cin>>n;
rep(a,1,3) rep(b,1,3) rep(c,1,3) rep(d,1,3) rep(e,1,3) rep(f,1,3)
rep(g,1,3) rep(h,1,3) rep(i,1,3) rep(j,1,3)
if(a+b+c+d+e+f+g+h+i+j==n){
ans++;
}
cout<<ans<<endl;
rep(a,1,3) rep(b,1,3) rep(c,1,3) rep(d,1,3) rep(e,1,3) rep(f,1,3)
rep(g,1,3) rep(h,1,3) rep(i,1,3) rep(j,1,3)
if(a+b+c+d+e+f+g+h+i+j==n){
cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<" "<<f<<" "<<g<<" "<<h<<" "<<i<<" "<<j<<endl;
}
return 0;
}
代码2
这个题目还可以再优化,如果a,b,c,d,e加起来已经超过n,那么显然f,g,h,i,j就没有继续尝试枚举的必要了。针对这个问题,对这道题目进行枚举剪枝——限定每个变量的范围。比如e,在满足1<=e<=3的同时,还能做到一个更好的估计:n-15-a-b-c-d<=e<=n-5-a-b-c-d。这个不等式左侧是假设后面都取3,那么e至少这么大;右侧是假设会面都取1,那么3最大这么大。同时使用数组li来记录符合要求的答案,这样就不需要枚举两次大循环,又进一步加快了速度。
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for(int i=max(1,a);i<=min(3,b);i++)
int li[60000][10];
int main(){
int n,ans=0,cnt=10;
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]<<" ";
}
cout<<endl;
}
return 0;
}