P2089 烤鸡 【枚举】【深搜】

4 篇文章 0 订阅
4 篇文章 0 订阅

题目

题目描述

猪猪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 );
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值