- 问题描述
-
题目很简单,把一个正整数分割成N个正整数之和。但是你得把所有的划分方法列出来,以字典序升序排序。对于每种划分方法,小的数字在前面。
- 输入
-
有多组数据,以EOF结尾。
每行一个数字N(1 ≤ N ≤ 50),代表你要划分的整数。
- 输出
-
对于每组数据,以字典序升序输出每种划分方法。每个数字之间以空格隔开,每种划分方法以回车隔开。
数据组之间不需要空行。
- 样例输入
-
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
7
- 用搜索可以做,思路是,设置一个sum变量,初始为0,每次给他加上因子,并判断加上后是否超过n,如果超过,则当前方案不行,回溯,否则,继续递归下一个位置的因子,注意,下一个位置的因子一定要比本位置的大或者相等,所以在加i的时候,就得判断,否则会出现重复和没有字典序的问题
#include<stdio.h>
int num[55];
int sum=0;
void dfs(int cur,int n)
{
if(sum==n)//如果sum就等于n,那么得输出方案
{
for(int i=1;i<cur-1;i++)//这个数组里存的就是sum当前的划分方案
printf("%d ",num[i]);
printf("%d\n",num[cur-1]);
}
else
{
for(int i=1;i<=n;i++)//对所有可能的因子遍历
{
if(i>=num[cur-1]) //为了字典序和不重复,加上判断
{
sum+=i;//i就是sum 的其中一个因子
if(sum<=n)//如果小于或等于n,记录i
{
num[cur]=i;
dfs(cur+1,n);//去寻找下一个位置的因子
sum-=i;//回溯时减去i
}
else//大于i表明方案不合适,回溯
{
sum-=i; //把i这个伪因子减掉
return ;
}
}
}
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
dfs(1,n);
}
return 0;
}