魔术师有m个碗每个碗可以放n个小球 现在共有X个小球 小球的大小一样 请问有多少种放法
魔术师有m个碗每个碗可以放n个小球 现在共有X个小球 小球的大小一样 请问有多少种放法
[解决办法]
/*
魔术师m个碗,每个碗可以装n个小球,现在共有x个小球,
小球是完全相同的,问有多少种放法?
例如:
1、输入:5 3 10 则有51种方法
2、输入:11 5 50 则有2992种方法
*/
#include <stdio.h>
#include <stdlib.h>
int put_Ball_InBox(int index, int *a, int cap, int ball);
void main()
{
int boxcnt ; //盒子数量
int capcnt;//每个盒子容纳小球的数量
int ballcnt;//小球的总数
int *boxs;
char *pool;
int count;//用来返回放置方法
int length = 0;
int i;
printf("Please input boxcnt,capcnt,ballcnt\n");
scanf("%d%d%d",&boxcnt,&capcnt,&ballcnt);
boxs = (int *)malloc(boxcnt * sizeof(int));
printf("boxs size:%d\r\n",sizeof(pool));
// 对boxs做初始化
for(i=0; i<boxcnt; i++)
{
boxs[i] = 1;
}
count = put_Ball_InBox(0, boxs, capcnt, ballcnt);
printf("共有 %d 种放置方法", count);
system("pause");
return 0;
}
//本函数规定,每个盒子至少放1个球
int put_Ball_InBox(int index, int *a, int cap, int ball) {
int i;
int start;
int count = 0;
int length = 0;
int leftBall = ball;
// 统计a的元素个数
while(*(a+length) != '\0')
{
length++;
}
//计算当前还剩多少球
for(i=0; i<index; i++) {
leftBall -= a[i];
}
//如果一个球都不剩了,则此套方案失败,返回0
if(leftBall<=0) {
return 0;
}
//如果正在考察最后一个盒子
if(index == length-1) {
//如果剩余的球少于盒子容量上限
if(leftBall<=cap) {
//则打印显示此放置方案,并返回1
a[index] = leftBall;
for(i=0; i<length; i++) {
printf("%d ", a[i]);
}
printf("\r\n");
return 1;
}else { //反之,此方案不可行,返回0
return 0;
}
}
//假设后面的盒子全放满,则当前盒子最少放多少个球
start = leftBall - (length - index - 1) * cap;
if(start>cap) { //若最少也要超过盒子容量上限,则此方案失败,回溯
return 0;
}else if(start <1) {//若其值小于等于0,则将其修真恶搞为1,因为至少要放1个球
start = 1;
}
//开始递归调用
for(i=start; i<=cap; i++) {
a[index] = i;
count += put_Ball_InBox(index+1, a, cap, ball);
}
return count;
}