#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#define M 100
typedef unsigned int UINT;
UINT queue[M+1]={0};
int p(UINT n, UINT m, UINT pos);
UINT cnt=0;
int main()
{
UINT n,pos;
printf(" =========正整数分解程序(递归版)===/n");
printf("输入正整数n,本程序将把它分解成不/n大于它的数字的和的形式/n");
printf("================================/n/n");
printf("输入 n(>0): ");
while(scanf("%d",&n)!=EOF)
{
if(n<0)
exit(-1);
//初始化
queue[1]=n;
p(n, n,pos=1);
printf("/n正整数%d有总共%d种分割方法/n",n,cnt);
}
return 0;
}
/*
函数p把第一个参数n表示的正整数分割成最大因子为m的分割。
如n=5,m=3,则分割为5=5=3+2=3+1+1=2+2+1=2+1+1+1=1+1+1+1+1
每一个分割的第一个因子(最大的因子)都不大于n。
利用递归来实现
*/
int p(UINT n, UINT m,UINT pos)
{
UINT d=0,i; //d用来保存n-m
//如果m>n,n不可能分解为比自己还大的数字的和,所以m最多为n
if(m>n) m=n;
//递归结束的条件:当n,m中有一个为1时
if(m==1 || n==1)
{ /*把pos之前的所有的数都打印出来。m,n中有一个是1,表示已经
到达最后的数字了,这时候才需要打印 */
for(i=1;i<pos;i++)
printf("%3d ", queue[i]);
for(i=0;i<n;i++)
printf("%3d ", 1);
printf("/n");
cnt++; //分割种数加一
return 0;
}
else if( n==m ) //保证n是正整数,m=n(>1)表示分割进行到了最右边的数
{
//把pos之前的所有的数都打印出来。只有到达分解成的最后的数字的时候才需要打印
for(i=1; i<pos;i++)
printf("%3d ", queue[i]);
printf("%3d/n", m);
cnt++; //分割种数加一
m--; //减1之后交给下面的程序来进行分割
}
do
{
d=n-m;
queue[pos]=m; //把队列当前位置pos的值置为m
p(d,m,pos+1); //对差d进行最大数字为m的分解。
m--;
}
while(m>=1);
return 0;
}