正整数分解程序(递归版)

来源:互联网 发布:美国通用航空数据 编辑:程序博客网 时间:2024/06/05 01:55

#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;
}