备战蓝桥杯 Day2

1318:【例5.3】自然数的拆分

【题目描述】

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。

当n=7共14种拆分方法:

7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
total=14

【输入】

输入n。

【输出】

按字典序输出具体的方案。

【输入样例】

7

【输出样例】

7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
#include
using namespace std;
const int N = 1e2 + 10;
int cnt[N];
int n;
int s = 0;//记录搜索到的总和
void dfs(int depth)
{
	if (s > n)return;
	//5.终止条件
	if (s == n)
	{
		cout << n << "=";
		for (int i = 1; i < depth-1; i++)
		{
			printf("%d+", cnt[i]);
		}printf("%d", cnt[depth-1]);
		cout << endl;
	}
	//1.枚举方案
	for (int i = 1; i < n; i++)
	{
		//2.本题需要重复搜索故不需标记
		if (i>=cnt[depth-1])//组合问题
		{
			//3.搜索
			cnt[depth] = i;
			s += i;
			dfs(depth + 1);
			//4.回溯
			s -= i;
		}
	}
}
int main()
{
	cin >> n;
	dfs(1);
	return 0;
}
 代码优化
#include
using namespace std;
const int N = 1e2 + 10;
int cnt[N];
int n;
void dfs(int s,int depth)//s-当前搜索的总和
{
	if (s > n)return;
	//5.终止条件
	if (s == n)
	{
		cout << n << "=";
		for (int i = 1; i < depth-1; i++)
		{
			printf("%d+", cnt[i]);
		}printf("%d", cnt[depth-1]);
		cout << endl;
	}
	//1.枚举方案(枚举的时候直接排列变组合)
	for (int i = cnt[depth-1]; i < n; i++) {
		//2.本题需要重复搜索,则不需要加标记,故第二步略
		//3.搜索
		cnt[depth] = i;
		dfs(s+i,depth + 1);
		//4.回溯,若s作为状态传入dfs,则回溯的时候,s自动还原
    }
}
int main()
{
    cnt[0] = 1;//不置零会导致无限递归
	cin >> n;
	dfs(0,1);
	return 0;
}

你可能感兴趣的:(insist,蓝桥杯,职场和发展)