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

输入: n

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

我们以 n = 4 为例说明一下执行过程, 下附代码

 

我们以 n = 4 为例说明一下运行过程
阅读本段 一定要注意各个变量值的变化

cin >> n = 4, 进入func函数
此时 s = 4, t = 1;
for 循环 i = a[1-1] = 1
1 < 4 => a[1] = 1, s = 3;
s = 3 != 0 递归进入下一层 ***我们在这里做一下标记,方便回溯

第二层 s = 3, t = 2
i = a[2-1] = 1 	不知道为什么看第五行
i < s, i < n => a[2] = 1, s = 2;
s = 2 != 0 继续递归进入下一层 	***

第三层 s = 2, t = 3;
步骤类似前面的
最后 s = 1, a[3] = 1
s = 1 != 0 继续递归进入下一层 ****

第四层 s = 1, t = 4;
这一层for循环只执行一次 因为 i = 1, s = 1
a[4] = 1, s = 0;
print(t);	输出了 4 = 1+1+1+1;

开始回溯
我们注意到 在第三层 s = 2, i = 1, 故for循环执行两次
第二次for循环 i = 2, s = 2
这一层变量的值 i = 2,s = 2, t = 3, a[0]~a[4] 都是 1
循环体里a[3] = i = 2, s = 2 - 2 = 0
执行print(t) 要注意一下print函数输出是a[1] 到 a[t]
所以输出的是 4 = 1 + 1 + 2;	下面的输出原因也是一样

至此第三层的for循环也执行完毕
变量值 a[0] = a[1] = a[2] = a[4] = 1, a[3] = 2;

回溯到第二层, 第二层的for循环只执行了一次
但是本层初始值 i = 1, s = 3, t = 2, 所以还有两次for循环没有执行
第二次for循环 i = 2
循环体内 i < n, a[2] = 2, s = 3 - 2 = 1
s != 0
注意了, 我们又要递归了	*** 标记一下, 一会回溯到此处

第五次递归
a[0] = 1, a[1] = 1, a[2] = 2, a[3] = 2, a[4] = 1;
s = 1, t = 3
初始i = a[2] = 2	注意前文数组a中值的变化 a[2] 已经是2了
i = 2, 但是 s = 1 	for循环不执行

直接回溯到刚才标记到地方, 进行第三次for循环
第二层第三次for循环 i = 3, s = 3, t = 2
3 < 4 => a[2] = 3  s = 3 - 3 = 0;
s = 0, 执行print(t) 输出 4 = 1 + 3

到此处 第二层的for循环执行完毕
a[0] = 1, a[1] = 1, a[2] = 3, a[3] = 2, a[4] = 1

回溯到第一层, 第一层初始 i = 1, s = 4, 应执行四次for循环
现执行第二次for循环
i = 2, s = 4, t = 1
2 < 4 => a[1] = 2, s = 4 - 2 = 2
s = 2 != 0 进行递归

第六次递归
s = 2, t = 2
a[0] = 1, a[1] = 2, a[2] =3, a[3] = 2, a[4] = 1
初始 i = a[2-1] = 2,  s = 2	 执行一次for循环
i = 2 < 4 => a[2] = 2, s = 2 - 2 = 0;
s = 0 执行print(t) 输出 4 = 2 + 2	// 在此处所有情况以输出完毕
执行完毕, 回溯

回溯到第一层
执行第三次for循环
i = 3, s = 4, t = 1
i < n =>	a[1] = 3, s = 4 - 3 = 1;
s = 1 != 0 进行递归

第七次递归
a[0] = 1, a[1] = 3, a[2] = 3, a[3] = 2, a[4] = 1;
初始 s = 1, t = 2, i = a[2-1] = 3
i > s, 不执行for循环,直接回溯

回溯到第一层
执行第四次for循环
i = 4, s = 4, t = 1
循环体内 i = 4, n = 4, i < n 不成立
往下不在执行, 跳出循环

至此所有程序执行完毕, 返回到主函数


 

#include <iostream>
using namespace std;
const int MAXN = 100000+7;

int n, total = 0;
int a[MAXN] = {1};	//	初始a[0] = 1, 其余全为0

void print(int t)
{
	total ++;
	cout << n << "=";
	for(int i=1; i<=t; i++)
	{
		if(i == t)	// 最后一个数时执行这一步
			cout << a[i] << endl;
		else
			cout << a[i] << "+";
	}
}
int func(int s, int t)
{
	for(int i=a[t-1]; i<=s; i++)
	{
		if(i < n)
		{
			a[t] = i;
			s = s - i;
			if(s == 0)
				print(t);
			else
				func(s, t+1);
			s += i;
		}
	}
	return 0;
}

int main()
{
	cin >> n;
	func(n, 1);
	cout << total << endl;


	return 0;
}