Python算法100例-2.6 分糖果

文章讲述了如何使用循环和选择结构解决10个小孩分糖果问题,通过逐步分配和调整糖果数量,最终使得所有孩子拥有相同数量的糖果。经过17次分配后,每个孩子有18块糖果。
摘要由CSDN通过智能技术生成

完整源代码项目地址,关注博主私信'源代码'后可获取

1.问题描述

10个小孩围成一圈分糖果,老师分给第1个小孩10块,第2个小孩2块,第3个小孩8块,第4个小孩22块,第5个小孩16块,第6个小孩4块,第7个小孩10块,第8个小孩6块,第9个小孩14块,第10个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块。问经过这样几次后大家手中的糖一样多?每人各有多少块糖?

2.问题分析

根据题意,10个小孩开始时所拥有的糖果数是不同的,但分糖的动作却是相同的,即“所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块”。因此,这是一个典型的可使用循环结构来解决的问题。

将老师开始给每个小孩分配的糖果数作为循环的初始条件,以“所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块”这个重复的动作作为循环体,循环的结束条件为所有小孩手中的糖块数一样多。在循环体中,还需要判断糖块数的奇偶性,奇偶性不同完成的操作也不相同,显然这需要使用一个选择结构来实现。

3.算法设计

在问题分析中,我们已经确定了该问题使用循环结构来解决。那么如何存放每个小孩初始时所拥有的糖果数呢?这里考虑使用数组来存放老师开始给每个小孩分配的糖果数,因为有10个小孩,故定义一个长度为10的整型数组即可。在循环过程中,糖果每经过一次重新分配,就打印输出一次,直到最后一次打印时,10个小孩所拥有的糖果数都相同,此时结束循环。

4.确定程序框架

(1)定义整型数组存放初始条件

# sweet[0]=10表示第一个小孩的糖果数为10,以此类推
sweet = [10, 2, 8, 22, 16, 4, 10, 6, 14, 20]

将老师开始给每个小孩分配的糖果数存放到sweet数组中。

(2)循环结构实现框架

while (10个孩子手中的糖果数不相同):                         # 若不满足要求则继续循环
# 将每个孩子手中的糖果数平分为两份
    for i in range(0, 10):
        if sweet[i] % 2 == 0:                               # 若为偶数则直接分出一半
            sweet[i] = sweet[i] // 2
            t[i] = sweet[i]
        else:                                                               # 若为奇数则加1后再分出一半
            sweet[i] = (sweet[i] + 1) // 2
            t[i] = sweet[i]

    # 将分出的一半糖果给右边的孩子
    for n in range(0, 9):
        sweet[n + 1] = sweet[n + 1] + t[n]
    sweet[0] += t[9]
    j += 1
    printResult(sweet, j)                                   # 输出当前每个孩子手中的糖果数


上面的代码在while循环结构中又包含了两个for循环。

while循环的循环条件为“10个孩子手中的糖果数不相同”,第一个for循环用来将当前每个孩子手中的糖果分成一半,同时将分配结果保存在数组t中。在分配时注意区分奇偶数糖果分配方式的不同。第二个for循环用来将每个孩子手中已分好的一半的糖果给右边的孩子,由于第一个for循环中已经将每个孩子手中一半的糖果数保存在t数组中了,因此可直接利用t数组中的值修改sweet数组中的对应元素值。又由于“10个小孩围成一圈分糖果”,因此,sweet[9]右边的元素为sweet[0]。

(3)定义judge()函数

judge()函数用来判断每个孩子手中的糖果数是否相同。judge()函数的参数为整型数组,它可以判断该数组中各个元素的值是否相同,如果数组中所有元素的值都相同,则judge()函数返回值为0,否则judge()函数返回值为1。

judge()函数代码如下:

# 判断每个孩子手中的糖果数是否相同
def judge(candy):
    for i in range(0,10):
        if candy[0] != candy[i]:
            return 1                                # 不相同返回1
    return 0                                        # 相同返回0

程序流程图如图所示。

在这里插入图片描述

5.完整的程序

根据上面的分析,编写程序如下:

%%time
# 分糖果

# 判断每个孩子手中的糖果数是否相同
def judge(candy):
    for i in range(0,10):
        if candy[0] != candy[i]:
            return 1     # 不相同返回1
    return 0   #相同返回0


def giveSweets(sweet, j):
    t = [0] * 10
    while (judge(sweet)):  # 若不满足要求则继续循环
        # 将每个孩子手中的糖果数分成一半
        for i in range(0, 10):
            if sweet[i] % 2 == 0:  # 若为偶数则直接分出一半
                sweet[i] = sweet[i] // 2
                t[i] = sweet[i]
            else:  # 若为奇数则加1后再分出一半
                sweet[i] = (sweet[i] + 1) // 2
                t[i] = sweet[i]

        # 将分出的一半糖果给右边的孩子
        for n in range(0, 9):
            sweet[n + 1] = sweet[n + 1] + t[n]
        sweet[0] += t[9]
        j += 1
        printResult(sweet, j)

# 输出列表中每个元素的值
def printResult(s, j):

    print("%4d" %j , end=" ")

    k = 0
    while k < 10:
        print("%4d" % s[k], end=" ")
        k += 1
        j += 1
    print()


if __name__=="__main__":
    # 定义一个列表来存储老师给每个孩子分配的糖果数
	# sweet[0]=10表示第一个小孩的糖果数为10,以此类推
    sweet = [10, 2, 8, 22, 16, 4, 10, 6, 14, 20]
    print("child  1    2    3    4    5    6    7    8    9   10")
    print("..........................................................")
    print("次数   糖果数")
    # 输出每个孩子手中的糖果数
    j = 0
    print("%4d" % j, end=" ")
    for i in range(len(sweet)):
        print("%4d" % sweet[i], end=" ")
    print()
    giveSweets(sweet,j)  # 分糖果

child  1    2    3    4    5    6    7    8    9   10
..........................................................
次数   糖果数
   0   10    2    8   22   16    4   10    6   14   20 
   1   15    6    5   15   19   10    7    8   10   17 
   2   17   11    6   11   18   15    9    8    9   14 
   3   16   15    9    9   15   17   13    9    9   12 
   4   14   16   13   10   13   17   16   12   10   11 
   5   13   15   15   12   12   16   17   14   11   11 
   6   13   15   16   14   12   14   17   16   13   12 
   7   13   15   16   15   13   13   16   17   15   13 
   8   14   15   16   16   15   14   15   17   17   15 
   9   15   15   16   16   16   15   15   17   18   17 
  10   17   16   16   16   16   16   16   17   18   18 
  11   18   17   16   16   16   16   16   17   18   18 
  12   18   18   17   16   16   16   16   17   18   18 
  13   18   18   18   17   16   16   16   17   18   18 
  14   18   18   18   18   17   16   16   17   18   18 
  15   18   18   18   18   18   17   16   17   18   18 
  16   18   18   18   18   18   18   17   17   18   18 
  17   18   18   18   18   18   18   18   18   18   18 
CPU times: user 2.09 ms, sys: 1.6 ms, total: 3.69 ms
Wall time: 3.04 ms

6.运行结果

从输出结果可知,经过17次分糖过程后,10个孩子手中的糖果数相等,都为18块。

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘逸高铁侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值