自然数的拆分问题(C语言)

题目

题目描述

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。现在给你一个自然数n,要求你求出n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数n。

输出格式

输出:若干数的加法式子。

输入输出样例

输入 #1复制

7

输出 #1复制

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

题解

1. 首先明确,这是一个关于DFS的回溯问题,DFS的特征是会把所有情况都考虑出来,所有用DFS。回溯就是将走过的路径打印出来。

2. 怎么用DFS,这个题目中的DFS是用来分解自然数的,我的做法是运用DFS从1开始加,一直加到加数(sum)等于输入的n,判断一下sum==n。

3.要注意的是要回溯路径,这时候需要一个t(t代表一共加了几次)和一个数组x[](注意这个数组一定要是全局变量)来记录一下每一步的被加数,用一个pri函数打印,要向这个pri函数中传递的参数是最后的t(就是满足一次sum==n条件时的最后t的值)的值。

4.DFS的限制条件,就是必须要是一个加法,要满足加法的条件,被加数的个数要大于1,这个就与t的值有关了,t的初始值为0,当t>1是才能成为加法,所以再sum==n的条件后面还要加一个条件t>1。

5.我写的DFS中有三个形参,分别代表从x开始加,加数和,t上面已经做了解释。

6.每加一次要用x[]记录一下,当前所加的数的值,还要用sum记录当前的加数和。

7.每次调用DFS后返回时要取消记录。

代码如下

#include"stdio.h"
#include"string.h"
int n;
int b[8];
void pri(int i)
{
	int t;
	for(t=0;t<i;t++)
	{
		if(t==0)
		printf("%d",b[t]);
		else 
		printf("+%d",b[t]);
	}
	printf("\n");
}
void dfs(int x,int sum,int t)//x表示从几开始加,sum表示加数和 
{
	int i;
	if(sum==n&&t>1)
	{
		pri(t);//记录一下总数 
		return;
	} 
	for(i=x;i<=n-sum;i++)//保证加数,小于或者等于n 
	{
		b[t]=i;
		sum+=i;
//		printf("x=%d sum=%d t=%d\n",x,sum,t);
		dfs(i,sum,t+1);//取消记录 
		sum-=i;
	}
}
int main()
{
 	scanf("%d",&n);
 	dfs(1,0,0);
 	return 0;
} 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值