问题描述:给定一个字自然数N,由N开始依次产生半数集set(n)中的数如下;
(1)n∈set(n);
(2)在N的左边添加上一个自然数,但该自然数不能超过最近添加的数的一半;
(3)按此规则进行处理,直到不能添加自然数为止。
例如:set(6)={6,16,26,126,36,136}.半数集set(6)中有6个元素。注意,该元素不是多重集。集合已经有的元素不能添加到集合中。
算法分析:
因为半数集不是多重集数,所以集合已有额元素不能重复添加,
1.由于0<n<201,那么0<n/2<=100,因此在此计算的时候可能产生重复的元素是两位。
2.一个两位数的x重复产生的条件是,在1位数y=x%10的半数集中产生x,因此就有x/10<y/2,即2(x/10)<=x%10
例如;set(24)={24,...,1224,..324,...,1224,....}
前者的1224组合是1+2+24;后者的1224是12+24
完整代码:
#include<stdio.h>
int group[300]={0};
long Half(int n)
{
if(group[n]>0) //跳出循环
return group[n];
else
{
group[n]=1;
for(int i=1;i<=n/2;i++) //不能超过半数
{
group[n]=group[n]+Half(i);//递归
if((i>10)&&(i/10<=(i%10)/2))
group[n]=group[n]-group[i/10];
}
}
return group[n];
}
int main()
{
int number;
printf("输入数字:");
scanf("%d",&number);
Half(number);
printf("%d",Half(number));
}