首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

魔术师有m个碗每个碗可以放n个小球 现在共有X个小球 小球的大小一样 请教有多少种放法

2013-06-25 
魔术师有m个碗每个碗可以放n个小球 现在共有X个小球 小球的大小一样 请问有多少种放法魔术师有m个碗每个碗

魔术师有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;
    }


热点排行