记录点滴成长:
整数划分的非递归算法
例如将整数6划分为如下:
6
5 1
4 2
4 1 1
3 3
3 2 1
3 1 1 1
2 2 2
2 2 1 1
2 1 1 1 1
1 1 1 1 1 1
如6有11个划分。
#include “stdio.h”
void Divinteger(int n)
{
if (n==1) //处理输入值为1的情况,因为如果输入1,就不用再划分
{
printf(“只有一种划分:1/n”);
return;
}
if (n == 2) //处理输入值为2 的情况,如果输入为2,只要写成1+1就可以了。
{
printf(“第1种划分:2/n”);
printf(“第2种划分:1 1/n”);
printf(“一共有2种划分!/n”);
return;
}
int *a =new int(n); //定义动态数组,因为当n大于2时,如3=2+1,这时就需要对2进行相似划分,其大小是不固定的,因而用动态数组。
int div=0; //每一行划分的数组下标
int k=1;//记录种类的值。
a[0] = n – 1;
a[1] = 1;
div = 2; //第二次一定划分为2个值。n-1和1
printf(“第%2d种划分:%d /n”,1,n);
int i;
do{
k++;
printf(“第%2d种划分:”,k);
printf(“%d”, a[0]);
for (i = 1; i < div; i++)
printf(” %d”, a[i]);
printf(“/n”);
int s = 0;
do{
s += a[–div];
}while (div >= 0 && a[div] == 1); //这里用来找到非1的可以继续划分的值,如5 1,通过这一部找到5;
if (div == -1)
break;
int d = a[div] – 1; //判断是否还有数字可以继续划分。
if (d == 1) //这句户用来为下一个循环做准备,
{
while (s > 0) //s存放着下一行一共有几个值
{
a[div++] = 1; //将下一行的值全部赋值为1.等待下一个循环输出。
s–;
}
}
else //表示还有值可以继续划分
{
do{
a[div++] = d;// 相当于向右移动一位,进入下一次划分(对4)
s -= d;
}while (s >= d); //得出a[0]=4
if (s != 0)
a[div++] = s; //得出a[1]=2 div=2
}
}while (1);
printf(“/n一共有 %d 种方法!/n/n”,k);
}
void main()
{
int n;
printf(“输入你要求的划分整数值:/n”);//输入n值
scanf(“%d”, &n);
Divinteger(n); //调用划分函数
}