问题描述: 任何一个大于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
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;
}