/* 利用递推法求最小数生成问题
例:按递增次序生成1个集合M的最小的n个数.M定义如下:
1、1属于M
2、若x属于M,则2x+1属于M,3x+1属于M
3、无别的数属于M
1为n个数中的第1个数,再右1递推出余下的n-1个数。从两个队列(2x+1,3x+1)选一个“排头”
(两个队列中,尚未选入的第1个小的数)送入数组M中。
*/
#include "stdio.h"
#define M 100
main()
{
int m[M];
int n,p2,p3,i;
m[1]=p2=p3=1; /* 设p2表示2x+1,p3表示3x+1 */
printf("please Input number:");
scanf("%d",&n);
for(i=2;i<=n;i++)
{
if(2*m[p2]==3*m[p3]) /* p2==p3 数组放入任一个,调整p2,p3*/
{
m[i]=2*m[p2]+1;
p2++;
p3++;
}
else if(2*m[p2]<3*m[p3])/* p2<p3 数组放入p2的排头,调整p2*/
{
m[i]=2*m[p2]+1;
p2++;
}
else /* p2>p3 数组放入p3的排头,调整p3*/
{
m[i]=3*m[p3]+1;
p3++;
}
}
/*OUTPUT*/
for(i=1;i<=n;i++)
{
printf("%4d",m[i]);
if(!(i%10)) printf(" ");
}
}
/* 利用递推法求阶乘问题
例:对给定的n(n<=100),计算并输出k的阶乘k!(k=1,2,...,n)的全部有效数字)
如:5!=120;
由于结果可能超过一般整数位数,所以用一个长度为1000的数组来存放结果的各个位数,
数组的第1个元素,存放结果的位数,数组其余部分,依次存放个位,十位,百位...
如:120,位数为3,则数组存放:3021(a[0]=3,a[1]=0,[2]=2,[3]=1)
*/
#include "stdio.h"
#include <malloc.h>
#define MAXN 1000
/*
方法pnext().已知a中的(k-1)!,求k!,只要把a中的结果再加a中原值k-1次(因为a中有一次了),就得k!
如:4!=24,把24再加上4次24就得120,即5!
*/
void pnext(int a[],int k)
{
/* m=a[0]存放整数位数,carry存放进位值*/
int *b,m=a[0],i,j,r,carry;
b=(int *)malloc(sizeof(int)*(m+1));
for(i=1;i<=m;i++)
b[i]=a[i]; /*把a中的结果放b中*/
for(j=1;j<k;j++) /*把a中的结果再(注意是再)加a中原值k-1次*/
{
for(carry=0,i=1;i<=m;i++)/*把a,b对应的每1位(总位数m)相加*/
{
r=(i<=a[0]?a[i]+b[i]:a[i])+carry;
a[i]=r%10; /*得出本位*/
carry=r/10; /*得出进位*/
}
if(carry)
a[++m]=carry; /*进位放a中,同时更新a中数字的总位数m*/
}
free(b);
a[0]=m;
}
void write(int *a,int k)
{
int i;
printf("%4d!=",k);
for(i=a[0];i>0;i--)
printf("%d",a[i]);
printf(" ");
}
main()
{
int a[MAXN],n,k;
printf("Enter the number n:");
scanf("%d",&n);
a[0]=1; a[1]=1; /*前两个位已知*/
write(a,1); /*输出1!=1 */
for(k=2;k<=n;k++)
{
pnext(a,k); /*计算k的阶乘*/
write(a,k); /*输出k的阶乘*/
getchar();
}
}