题目描述
任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。现在给你一个自然数n,要求你求出n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。
输入格式
输入:待拆分的自然数n。
输出格式
输出:若干数的加法式子。
输入输出样例
输入
7
输出
1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4
说明/提示
用回溯做。。。。
n <= 8
**
这是一道典型的DFS题目,与以往练习的题目不同的是这道题涉及到了“回溯”这一知识点,在不同的深搜之间并不只是简单的重复,而是要使状态回到原来应该有的样子在进行下一次深搜,好了不多BB,AC代码奉上。
**
#include <bits/stdc++.h>
using namespace std;
int m = 0; //m用来存放指定的数字
int num[10] = {1}; //num用来存放每一次相加的数字,第0位一定是1!!!
//定义输出函数
void output(int a);
//深搜!!
void dfs(int n, int t);
//极其简洁的主函数
int main()
{
cin>>m;
search(m,1);
return 0;
}
//有点耐人寻味的深搜!建议在纸上写出流程图更好理解
void dfs(int n, int t){
int i = 0; //i表示每次相加的数字
for(i = num[t-1] ; i <= n; i++){ //注意一下i的取值哈!!
if(i < m){
num[t] = i; //存放数字
n -= i; //存放完了当然是减去相应的值
if(n == 0) print(t); //已经减完了当然直接输出
else search(n,t+1); //继续深搜,t+1代表着要在num中排下一位了
n += i; //!!!千万别忘了回溯啊!!!
}
}
}
//输出函数!!
void output(int a){
//!!千万注意,这里的i要从1开始,
for(int i = 1 ; i <= a ; i ++){
cout<<num[i];
if(i != a) cout<<"+";
}
cout<<endl;
}