对于任意大于 1的自然数 n,总是可以拆分成若干个小于 n 的自然数之和。
现请你编写程序求出 n 的所有拆分。
输入格式
输入文件共一行,包含一个自然数,即要拆分的自然数 n(1≤n≤20)。
输出格式
输出文件有若干行,每行包含一个等式,即代表一种可行的拆分(格式与顺序参见样例)。
Sample 1
Inputcopy | Outputcopy |
---|---|
5 | 5=1+1+1+1+1 5=1+1+1+2 5=1+1+3 5=1+2+2 5=1+4 5=2+3 |
首先我们可以发现拆分结果的例子中后面的数总是大于或小于前面的数。所以本题不x个数(1<=x<=n)使其和为n那么简单,而是要注意前后的大小关系。首先,我们肯定需要对每一种可能的结果进行遍历,从中再加以判断是否符合题意,符合的话就将其存储并加以输出,否则不进行输出。以下就是相关的算法。
#include<stdio.h>
void dfs(int x,int c);
int n,d[20];
int main()
{
scanf("%d",&n);
dfs(0,0);
}
void dfs(int x,int c)
{
if(x>n)
{
return;
}
else if(x==n&&c!=1)
{
printf("%d=%d",n,d[0]);
for(int i=1;i<c;i++)
{
printf("+%d",d[i]);
}
printf("\n");
return ;
}
else
{
for(int i=1;i<=n-x;i++)
{
if(c==0)
{
d[c]=i;
dfs(x+i,c+1);
}
else
{
if(i>=d[c-1])
{
d[c]=i;
dfs(x+i,c+1);
}
}
}
}
}
以上就是实现相关功能的算法,或许这里就有人说,这个主编是个狗东西,连注释都不写!
嘿嘿,别着急嘛,待我细细道来。
void dfs(int x,int c)//x表示的是已经找出的数字之和,c表示的找出的数字的个数。
{
if(x>n)//如果和大于n,则抛弃本次结果,并且进行回溯。
{
return;
}
else if(x==n&&c!=1)//注意题中没有出现5=5的结果,因此应该排除c=1的情况
{
printf("%d=%d",n,d[0]);
for(int i=1;i<c;i++)
{
printf("+%d",d[i]);
}
printf("\n");//输出格式
return ;
}
else
{
for(int i=1;i<=n-x;i++)
{
if(c==0)
{
d[c]=i;//存储答案
dfs(x+i,c+1);//递归深入,进行下一个数字的查找
}
else//记得与前面存储的数字比较大小,如果该数字是第一个,则只需要存储就可以了
{
if(i>=d[c-1])
{
d[c]=i;//存储答案
dfs(x+i,c+1);//递归深入,进行下一个数字的查找
}
}
}
}
}
以上就是该题的解法以及需要注意的地方。
最后,小编祝大家编程能力步步高升哈。