NOJ [1046]整数划分

  • 问题描述
  • 题目很简单,把一个正整数分割成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; 
}


你可能感兴趣的:(NOJ [1046]整数划分)