博德之门 艾黎归队:这道算法题怎么做啊?

来源:百度文库 编辑:中科新闻网 时间:2024/05/06 00:46:38
有个自然数K
求大于0小于K的自然数相加等于K的所有组合
要求:这些自然数必须互不相等
组合之间不准重复
这是我参加面试的题目,原题中K=10,可能的组合不多,可以自己数出来,由此我想如果推广到任意自然数会怎样(K>2)?
大家只需说出算法的思想,用何种语言并不重要(最后是类C)。
不知道会不会很困难。

定义函数如下:
int Fun(int sum,int K);该函数计算所有大于0,小于K的数的组合,这些组合的和等于sum;
该函数返回值为组合个数;
该函数实现如下:
int Fun(int sum,int K)
{
//如果sum小于0,则不存在该种组合;
if(sum<0)
return 0;
//如果sum等于0,存在一种组合,即0=0;(这是临界状态)
if(sum == 0)
return 1;
//如果所有小于K的值得和小于sum,则不存在组合;
if(K*(K-1)<2*sum)
return 0;
//如果所有小于K的值的和等于sum,则存在一种组合,即1+…k-1
if(K*(K-1)==2*sum)
return 1;
int tmp = 0;
int i;
//核心循环;
for(i=K-1;i>0;--i)
{
tmp += Fun(sum-i,i);
}
return tmp;
}
核心循环可以解释为:
题目可以分解为:最大数为i,的所有组合;如:
假如是你面试的题目:则有以下组合;
9+1
8+2
7+3
7+2+1
6+4
6+3+1
5+3+2
4+3+2+1
如果你想输出这些组合,可以在程序中的返回前,进行输出;
可能说的不太明白;可以继续完善;
可以给我发消息,或者继续补充问题;

如需要源程序,可直接说明;可以做出来;

-----------------------------------------------------------
源代码如下:别忘了给分!!呵呵。
#include <stdlib.h>
int *Number;
int Kk;

int Fun(int sum,int K)
{
//如果sum小于0,则不存在该种组合;
if(sum<0)
return 0;
//如果sum等于0,存在一种组合,即0=0;(这是临界状态)
if(sum == 0)
{
int i;
printf("%d=",Kk);
for(i=1;i<=Number[0];++i)
{
printf("%d",Number[i]);
if(i>=Number[0])
break;
printf("+");
}
printf("\n");
return 1;
}
//如果所有小于K的值得和小于sum,则不存在组合;
if(K*(K-1)<2*sum)
return 0;
//如果所有小于K的值的和等于sum,则存在一种组合,即1+…k-1
if(K*(K-1)==2*sum)
{
int i;
printf("%d=",Kk);
for(i=1;i<=Number[0];++i)
{
printf("%d",Number[i]);
if(i>=Number[0])
break;
printf("+");
}
for(i=K-1;i>0;--i)
{
printf("+%d",i);
}
printf("\n");
return 1;
}
int tmp = 0;
int i;
//核心循环;
for(i=K-1;i>0;--i)
{
Number[Number[0]+1]=i;
Number[0]++;
tmp += Fun(sum-i,i);
Number[0]--;
}

return tmp;
}

int main(int argc, char* argv[])
{
printf("Please input the Number:");
scanf("%d",&Kk);
Number = (int *)malloc((Kk + 1)*sizeof(int));
Number[0]=0;
int i=Fun(Kk,Kk);
printf("%d,Hello World!\n",i);
return 0;
}

我也临时想到个解法:输入K后,生成一个长为K的动态数组a,先初始化为全0,然后用回溯法,每选一个数i,就将a[i]置为1。

你是要怎么解啊 是数学题吗 那就麻烦了
还是编程题啊
你怎么不说用什么语言编程啊
说出来 我教你

真是不错的题目,
临时想不到解法,不过想到一个题示,
例如:K=55
则1+2+3+4...+10 = 55
故 最多是由10个数字加总
不可能由11个数字加总.

还是不懂你的意思,比如3为什么不行,1+2=3;
“有个自然数K ”:k=3
“求大于0小于K的自然数相加等于K的所有组合”:
大于0小于3的正好有1,2;1+2又等于3,为什么不符合要求?

For(int i=0;i++;i<k)
{
For(int j=i+1;j++;j<k)
{
int total=i+j;
IF(total==k)
{
.......
}
}
}
用这个算法,看行不行