题目
题目描述
猪猪Hanke特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke吃鸡很特别,为什么特别呢?因为他有10种配料(芥末、孜然等),每种配料可以放1—3克,任意烤鸡的美味程度为所有配料质量之和
现在,Hanke想要知道,如果给你一个美味程度,请输出这10种配料的所有搭配方案
输入格式
一行,n<=5000
输出格式
第一行,方案总数
第二行至结束,10个数,表示每种配料所放的质量
按字典序排列。
如果没有符合要求的方法,就只要在第一行输出一个“0”
解析
正解直接暴力枚举。只不过代码不太好看的亚子。(或许不需要这么多大括号。。。)
int main()
{
int n;
cin >> n;
if( n > 3 * 10 || n < 1 * 10)
{
cout << 0 << endl;
return 0;
}
int ans = 0;
for(int i1 = 1 ; i1 <= 3 ; i1 ++)
{
for(int i2 = 1 ; i2 <= 3 ; i2 ++)
{
for(int i3 = 1 ; i3 <= 3 ; i3 ++)
{
for(int i4 = 1 ; i4 <= 3 ; i4 ++)
{
for(int i5 = 1 ; i5 <= 3 ; i5 ++)
{
for(int i6 = 1 ; i6 <= 3 ; i6 ++)
{
for(int i7 = 1 ; i7 <= 3 ; i7 ++)
{
for(int i8 = 1 ; i8 <= 3 ; i8 ++)
{
for(int i9 = 1 ; i9 <= 3 ; i9 ++)
{
int i10 = n - i1 - i2 - i3 - i4 -i5 - i6 - i7 - i8 - i9;
if(i10 <= 0 || i10 >3) continue;
ans ++;
}
}
}
}
}
}
}
}
}
cout << ans << endl;
for(int i1 = 1 ; i1 <= 3 ; i1 ++)
{
for(int i2 = 1 ; i2 <= 3 ; i2 ++)
{
for(int i3 = 1 ; i3 <= 3 ; i3 ++)
{
for(int i4 = 1 ; i4 <= 3 ; i4 ++)
{
for(int i5 = 1 ; i5 <= 3 ; i5 ++)
{
for(int i6 = 1 ; i6 <= 3 ; i6 ++)
{
for(int i7 = 1 ; i7 <= 3 ; i7 ++)
{
for(int i8 = 1 ; i8 <= 3 ; i8 ++)
{
for(int i9 = 1 ; i9 <= 3 ; i9 ++)
{
int i10 = n - i1 - i2 - i3 - i4 -i5 - i6 - i7 - i8 - i9;
if(i10 <= 0 || i10 >3) continue;
// ans ++;
cout << i1 << " " << i2 << " " << i3 << " " << i4 << " "
<< i5 << " " << i6 << " " << i7 << " " << i8 << " "
<< i9 << " " << i10 << endl;
}
}
}
}
}
}
}
}
}
}
其实也可以使用宏定义:
#define f(x) for(i[x]=1;i[x]<=3;i[x]++)
如果使用深搜,而你只想用一个二维数组来表示,并且这个二维数组的第一列你又都要用来表示这个方法是否可行时,千万不要忘记函数在回溯时,没有回溯到的地方是没有数值的。。。这就是为什么要多一个memcpy的拷贝操作。
int cnt = 0;
int ans[10005][11];
int dfs(int cur , int left)
{
if(cur == 10)
{
if(left >= 1 && left <= 3)
{
ans[cnt][cur] = left;
ans[cnt][0] = 1;
cnt ++;
memcpy(ans[cnt] , ans[cnt - 1] , 10 * sizeof(int));
return 1;
}
}
if(left < (10 - cur + 1) || left > (10 - cur + 1) * 3) return 0;
for(int i = 1; i <= 3 ; i ++ )
{
ans[cnt][cur] = i;
dfs(cur + 1 , left - i);
}
}
int main()
{
int n ;
cin >> n;
if( n < 10 || n > 30)
{
cout << 0 << endl;
return 0;
}
memset(ans , 0 , sizeof(ans));
dfs(1 , n);
cout << cnt << endl;
for(int i = 0 ; i < cnt ; i++)
{
if(ans[i][0])
{
// cout << i << " -- " << ans[i][0] << " : " ;
for(int j = 1; j <= 10 ; j ++)
cout << ans[i][j] << " ";
cout << endl;
}
}
}
如果不选择作死,还是比较顺利的。
int ans1[11];
int ans2[10005][11];
int dfs(int cur , int left)
{
if(cur == 10)
{
if(left >= 1 && left <= 3)
{
ans1[cur] = left;
for(int i = 1; i <=10 ; i++)
ans2[cnt][i] = ans1[i];
cnt ++;
return 0;
}
}
for(int i = 1; i <= 3 ; i ++)
{
if(left < (10 - cur + 1) || left > 3 * (10 - cur + 1))
continue;
ans1[cur] = i;
dfs(cur + 1, left - i );
}
}