B1005 继续(3n+1)猜想

在这里插入图片描述
收集被覆盖的数字,从原列表剔除这些数字。

n = eval(input())
ls = input().split()
c = []
d = []
def judge(num, d):  # 用于收集num覆盖的数字
    while num != 1:
        if num%2 == 1:
            num = (3*num+1)//2
            d.append(num)
        if num%2 == 0:
            num = num//2
            d.append(num)
    return d

k = []
for s in ls:
    c.append(eval(s))
    k += judge(eval(s), d)

k = list(set(k)) # 去重

for num in k: # 对输入的列表进行过滤,筛除d中收集的被覆盖的数字
    if num in c:
        c.remove(num)

c.sort()  # 对过滤后的列表排序
for num in c[::-1]:
    if num != c[0]: # 除最后一个元素后不添加空格,其余添加
        print(num, end=' ')
    else:
        print(num)

方法二:

  • 思路
    1 利用字典结构,标记被覆盖过的元素
    2 遍历处理完所有数字后,对字典中标志位为0的元素从大到小进行排序
    3 打印关键数,注意输出格式
n = eval(input())
nums = list(map(int, input().split()))
d = {}
d = d.fromkeys(nums, 0) #利用字典结构标记被覆盖过的元素
for temp in nums:
    while temp != 1:
        if temp % 2 == 0:
            temp //= 2
        else:
            temp = (3*temp + 1) // 2
        if temp in nums:
            d[temp] = 1

results = sorted(d.items(), key = lambda d : d, reverse = True)

flag = False
for result in results: #输出结果,注意控制格式
    if result[-1] == 0:
        print((' ' if flag == True else '') + "{}".format(str(result[0])), end = '')
        flag = True

思考:
在验证卡拉兹数时,如果直接使用remove将覆盖过的数直接从列表剔除,将无法得到正确结果?

n = eval(input())
nums = list(map(int, input().split()))


for temp in nums:
    print('present temp={}\npresent nums={}'.format(temp, nums))
    while temp != 1:
        if temp % 2 == 0:
            temp //= 2
        else:
            temp = (3*temp + 1) // 2
        if temp in nums:
            nums.remove(temp)
        print('modified temp={}\nmodified nums={}'.format(temp, nums))

'''
flag = False
for result in sorted(nums, reverse=True): #输出结果,注意控制格式
    print((' ' if flag == True else '') + "{}".format(result), end = '')
    flag = True
'''

运行结果:

6
3 5 6 7 8 11

present temp=3
present nums=[3, 5, 6, 7, 8, 11]
modified temp=5
modified nums=[3, 6, 7, 8, 11]
modified temp=8
modified nums=[3, 6, 7, 11]
modified temp=4
modified nums=[3, 6, 7, 11]
modified temp=2
modified nums=[3, 6, 7, 11]
modified temp=1
modified nums=[3, 6, 7, 11]

present temp=6
present nums=[3, 6, 7, 11]
modified temp=3
modified nums=[6, 7, 11]
modified temp=5
modified nums=[6, 7, 11]
modified temp=8
modified nums=[6, 7, 11]
modified temp=4
modified nums=[6, 7, 11]
modified temp=2
modified nums=[6, 7, 11]
modified temp=1
modified nums=[6, 7, 11]

present temp=11
present nums=[6, 7, 11]
modified temp=17
modified nums=[6, 7, 11]
modified temp=26
modified nums=[6, 7, 11]
modified temp=13
modified nums=[6, 7, 11]
modified temp=20
modified nums=[6, 7, 11]
modified temp=10
modified nums=[6, 7, 11]
modified temp=5
modified nums=[6, 7, 11]
modified temp=8
modified nums=[6, 7, 11]
modified temp=4
modified nums=[6, 7, 11]
modified temp=2
modified nums=[6, 7, 11]
modified temp=1
modified nums=[6, 7, 11]

观察nums列表和每次修改的temp不难发现,在遍历nums
列表时,只遍历了3、6、11。原因是因为使用remove操作使列表不断缩短,而与此同时,for循环根据序列序号对列表进行遍历,因此,只能遍历三轮。

解决:
对于包含remove操作剔除列表元素的遍历,for循环采用逆序遍历

#1005_test.py
n = eval(input())
nums = list(map(int, input().split()))


for temp in nums[::-1]: #####关键
    print()
    print('present temp={}\npresent nums={}'.format(temp, nums))
    while temp != 1:
        if temp % 2 == 0:
            temp //= 2
        else:
            temp = (3*temp + 1) // 2
        if temp in nums:
            nums.remove(temp)
        print('modified temp={}\nmodified nums={}'.format(temp, nums))

'''
flag = False
for result in sorted(nums, reverse=True): #输出结果,注意控制格式
    print((' ' if flag == True else '') + "{}".format(result), end = '')
    flag = True
'''

运行结果:

6
3 5 6 7 8 11

present temp=11
present nums=[3, 5, 6, 7, 8, 11]
modified temp=17
modified nums=[3, 5, 6, 7, 8, 11]
modified temp=26
modified nums=[3, 5, 6, 7, 8, 11]
modified temp=13
modified nums=[3, 5, 6, 7, 8, 11]
modified temp=20
modified nums=[3, 5, 6, 7, 8, 11]
modified temp=10
modified nums=[3, 5, 6, 7, 8, 11]
modified temp=5
modified nums=[3, 6, 7, 8, 11]
modified temp=8
modified nums=[3, 6, 7, 11]
modified temp=4
modified nums=[3, 6, 7, 11]
modified temp=2
modified nums=[3, 6, 7, 11]
modified temp=1
modified nums=[3, 6, 7, 11]

present temp=8
present nums=[3, 6, 7, 11]
modified temp=4
modified nums=[3, 6, 7, 11]
modified temp=2
modified nums=[3, 6, 7, 11]
modified temp=1
modified nums=[3, 6, 7, 11]

present temp=7
present nums=[3, 6, 7, 11]
modified temp=11
modified nums=[3, 6, 7]
modified temp=17
modified nums=[3, 6, 7]
modified temp=26
modified nums=[3, 6, 7]
modified temp=13
modified nums=[3, 6, 7]
modified temp=20
modified nums=[3, 6, 7]
modified temp=10
modified nums=[3, 6, 7]
modified temp=5
modified nums=[3, 6, 7]
modified temp=8
modified nums=[3, 6, 7]
modified temp=4
modified nums=[3, 6, 7]
modified temp=2
modified nums=[3, 6, 7]
modified temp=1
modified nums=[3, 6, 7]

present temp=6
present nums=[3, 6, 7]
modified temp=3
modified nums=[6, 7]
modified temp=5
modified nums=[6, 7]
modified temp=8
modified nums=[6, 7]
modified temp=4
modified nums=[6, 7]
modified temp=2
modified nums=[6, 7]
modified temp=1
modified nums=[6, 7]

present temp=5
present nums=[6, 7]
modified temp=8
modified nums=[6, 7]
modified temp=4
modified nums=[6, 7]
modified temp=2
modified nums=[6, 7]
modified temp=1
modified nums=[6, 7]

present temp=3
present nums=[6, 7]
modified temp=5
modified nums=[6, 7]
modified temp=8
modified nums=[6, 7]
modified temp=4
modified nums=[6, 7]
modified temp=2
modified nums=[6, 7]
modified temp=1
modified nums=[6, 7]

如前所述,遍历了列表中的每一个元素。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值