A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

唐宁鹤

初级黑马

  • 黑马币:

  • 帖子:

  • 精华:

练习4、有10个球分别为3红、3蓝、4白,球与球之间只有颜色的差别,现需要将这10个球放入3个盒子,要求每个盒子至少有一个白球,其余的球全部随机放,要求输出三个盒子里所有球的颜色,请用程序实现。

当时看到这道题,我的第一反应是要输出所有结果。然后我就拿笔算了一下,因为同种类球是相同的,所以白球共有3种可能性,红球和蓝球都是10种,那么总共是3*10*10=300种可能性。
考虑到电脑干活的特性,使用枚举法进行输出是最方便的,直接根据球数量枚举所有可能性,然后把数量对的输出即可。由于蓝球和红球相互独立,而且枚举的算法相同,所以定义了一个函数来完成这项工作,函数用枚举法工作,函数接受上一次三个框中球的数量,返回值是更新后三个框里球的数量,从第三个框开始加,加到最大数量就向前进1。然后程序外部进行三次循环,分别表示白球、蓝球和红球。最后可以在控制台看到300种不同的结果。
做完以后,问了一下同学才知道,用随机数输出一种情况就行了,好像多费了很多时间,不过这样确实学到了很多别的东西,也算有舍有得把。源程序在最后附上。

源程序如下:
def ball(number, color, *i, print_res = False):
    """枚举法输出每个框里球的数量

    :param number: 某种颜色求的数量
    :param color: 球的颜色
    :param i: 传入刚刚三个篮子里球的数量,防止每次都出来第一个结果
    :param print_res: 是否需要打印,只有在处理完红球以后才会打印
    :return: 球在三个篮子中的数量,在下一次调用的时候要重新输入
    """
    # 收上一次球的数量,因为后续循环里要+1,所以一开始要额外-1
    i1, i2, i3 = i
    i1 -= 1
    i2 -= 1
    while i1 < number:
        i1 += 1
        while i2 < number:
            i2 += 1
            while i3 < number:
                i3 += 1
                if (i1 + i2 + i3) == number:
                    dic[1][color] += i1
                    dic[2][color] += i2
                    dic[3][color] += i3
                    if print_res:
                        print(dic)
                    return i1, i2, i3
            i3 = -1
        i2 = -1
    i1 = 0
    # 如果i2、i3写0就会死循环,i1写-1就会多出球的个数为-1的情况
    # 在所有数都到最大以后还要返回一个值,否则外部会报错
    return i1, i2, i3


i_white = 0  # 唯一白球在哪个框里
i_blue = 0  # 蓝球在第一个框里的数量
i_red = 0  # 红球在第一个框里的数量
while i_white < 3:
    # 每循环完一次大循环以后要重置字典、和中间变量的值
    dic = {1: {"white": 1, "blue": 0, "red": 0},
           2: {"white": 1, "blue": 0, "red": 0},
           3: {"white": 1, "blue": 0, "red": 0}}
    blue_mid = (0, 0, 0)
    red_mid = (0, 0, 0)
    i_blue = 0
    i_white += 1  # 把白球放到下一个框里
    dic[i_white]["white"] += 1
    while i_blue < 3:
        # 循环完一个整红球循环以后,重置字典里蓝球的数量
        dic[1]["blue"] = 0
        dic[2]["blue"] = 0
        dic[3]["blue"] = 0
        i_red = 0
        blue_mid = ball(3, "blue", *blue_mid)
        i_blue = blue_mid[0]  # 调用传回的第一个框里蓝球的数量,用于判断
        while i_red < 3:
            # 输出一次以后,要重置字典里红球的数量
            dic[1]["red"] = 0
            dic[2]["red"] = 0
            dic[3]["red"] = 0
            red_mid = ball(3, "red", *red_mid, print_res=True)
            i_red = red_mid[0]  # 调用传回的第一个框里红球的数量,用于判断

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马