面试题:15个人围成圈数数 每逢报数为七的倍数就退出,一直循环下去 ,直到剩下最后一人 ,最后剩余的是第几个人,展示出退出的顺序

问题:
        15个人围成圈数数  每逢报数为七的倍数就退出,一直循环下去 ,
直到剩下最后一人 ,最后剩余的是第几个人,展示出退出的顺序。

代码:

PS:如果代码有哪里不理解可以看下面的分析,如果能理解,就不用浪费时间看下面的分析了

peo_num = 15
a = []
for i in range(peo_num):
    a.append(i+1)
# 被删除的元素
be_del = []
# 报数
num = 0
# 列表大于一个就循环
while len(a) >1:
    # 由于删除 元素后,索引会变,change_index 为索引改变的值
    change_index =0
    # 循环a列表
    for i in range(len(a)):
        # 报数
        num += 1
        # 如果num 为 7 的倍数
        if num % 7 == 0:
            # 删除元素,并添加到be_del 列表
            be_del.append(a.pop(i - change_index))
            # 由于删除了一个元素,本次循环的列表的索引就改变了1
            change_index += 1
    # 删除完元素。清除 change_index
    change_index = 0

print('最后剩下的人:',a)
print('退出的顺序::',be_del)

需求:

  • 1,求出,最后剩下的那个人
  • 2,退出的顺序
思路

首先,我们要15个人列出来,很显然,这应该用集合表示,根据题目,报数为7的倍数的,退出(退出的还要进行排序),这个集合要支持删除元素,我在这里就用两个列表了。

这道题的逻辑很简单,就是吧报数为 7 的倍数的元素的删除,并追加到一个新的列表中。

根据题目,15个人围成一圈,在人数发生改变的时候,但是报数不会重新开始,很显然,一个循环满足不了我们的需求,所以,我要用到两个循环,循环里面嵌套一个循环。外部的循环在人数大于1(即列表的长度大于1)的时候,报数不结束,内部的循环就是每个报数。在内部循环,进行判断,如果这个人的报数为7的倍数,则从列表中去除他,并且追加到一个新列表。

到这里,我们就可以开始代码,根据思路,我们可以写出下面的代码

peo_num = 15
a = []
for i in range(peo_num):
    a.append(i+1)
# 报数
num = 0
# 退出的列表
be_del  =  []
# 列表大于一个就循环
while len(a) >1:
    # 循环a列表
    for i in range(len(a)):
        # 报数
        num += 1
        # 如果num 为 7 的倍数
        if num % 7 == 0:
            # 删除元素,并添加到be_del 列表
            be_del.append(a.pop(i))
print('最后剩下的人:', a)
print('退出的顺序:', be_del)

运行结果:

 ...
	be_del.append(a.pop(i))
IndexError: pop index out of range

这里说我们删除的时候,索引超出了列表的长度,这里就会有人有疑问,
我们是根据列表的的索引来删除的,怎么会超出范围的。其实,这个问题简单,就是我在此之前删除了一个元素,列表的长度也会对应发生改变,但是在这个循环中 i 还是列表没有发生改变前的索引,当 i 是列表未改变的最大索引,当我们根据 i 去删除 改变后的列表对应的值的时候,就发现列表的长度不够,也就是,索引超出了列表的长度

那么这个问题怎么解决呢?
很简单,列表既然发生了变化,那么我们就把这个变化记下来,等下次列表发生变化的时候,这个变化给 i


peo_num = 15
a = []
for i in range(peo_num):
    a.append(i+1)
# 被删除的元素
be_del = []
# 报数
num = 0
# 列表大于一个就循环
while len(a) >1:
    # 由于删除 元素后,索引会变,change_index 为索引改变的值
    change_index =0
    # 循环a列表
    for i in range(len(a)):
        # 报数
        num += 1
        # 如果num 为 7 的倍数
        if num % 7 == 0:
            # 删除元素,并添加到be_del 列表
            be_del.append(a.pop(i - change_index))
            # 由于删除了一个元素,本次循环的列表的索引就改变了1
            change_index += 1
    # 删除完元素。清除 change_index
    change_index = 0

print('最后剩下的人:',a)
print('退出的顺序::',be_del)

结果:

最后剩下的人: [5]
退出的顺序:: [7, 14, 6, 15, 9, 3, 13, 11, 10, 12, 2, 8, 1, 4]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值