对于自然数大家都熟知,自然数就是大于等于0的整数,这里就不多说,那什么是自然数的拆分呢?顾名思义就是把自然数拆分成若干个小于n的自然数之和。话不多说上知识。
首先只需要输入一个自然数n,得出结果。当然如果n为偶数,可以拆分成n/2+n/2,如果n为奇数,那么就拆分成(n-1)/2+(n+1)/2.不断拆分,可以使用一个数组来记录拆分情况,每一个元素必须大于等于前一个元素。对于输入的自然数n,进行从1到n/2拆分,运用递归。
在主函数中输入n,并且从1遍历到n/2,并且将i存入数组a的第一个位置a[0],然后调用dfs函数,开始搜索。代码如下:
for(i=1;i<=n/2;i++)
{
a[0]=i;
dfs(n-i,1);
}
外部定义一个dfs函数进行搜索,代码如下:
void dfs(int s,int step)
加入判断条件就是当s等于0的时候就得到一种拆分方式,此时就遍历a[0]到a[step-1],代码如下:
if(s==0)
{
for(int i=0;i<step-1;i++)
cout<<a[i]<<"+";
cout<<a[step-1]<<endl;
}
否则继续进行搜索,使用一个for循环,如果当前拆分出来的值比step-1还要小,直接跳过,否则继续进行拆分,并且将该大于step-1的该值放入数组step中,然后再继续递归调用dfs函数。代码如下:
for(int i=1;i<=s;i++)
{
if(i<a[step-1])
continue;
a[step]=i;//存储
dfs(s-i,step+1);
}
总代码如下:
#include <iostream>
using namespace std;
int a[10];
void dfs(int s,int step)
{
if(s==0)
{
for(int i=0;i<step-1;i++)
cout<<a[i]<<"+";
cout<<a[step-1]<<endl;
}
else for(int i=1;i<=s;i++)
{
if(i<a[step-1])
continue;
a[step]=i;
dfs(s-i,step+1);
}
}
int main()
{
int n;
cin>>n;
int i;
for(i=1;i<=n/2;i++)
{
a[0]=i;
dfs(n-i,1);
}
return 0;
}
本题本质构造搜索树,需要掌握递归思想,主要是保证当前数据比前一个数据要大。,数组的作用就是记录值,直接输出该数组就行。