枚举法——蓝桥杯备赛

坚持坚持坚持!(解题步骤部分借鉴大佬们的代码,如有侵权请联系删除)


目录

一、枚举法

问题分析

代码示例

二、组合型枚举

问题分析

代码示例


一、枚举法

试题链接:第几个幸运数字

试题描述

到 X 星球旅行的游客都被发给一个整数,作为游客编号。X星的国王有个怪癖,他只喜欢数字3、5 和7。国王规定,游客的编号如果只含有因子:3、5、7,就可以获得一份奖品。
我们来看前 10 个幸运数字是3579152125273545,因而第 11 个幸运数字是: 49
小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。请你帮小明计算一下,59084709587505 是第几个幸运数字。


问题分析

用for循环的话数59084709587505太大了。我们可以把任意一个符合规定的数写成

(3**i)*(5**j)*(7**k)的形式,其中i,j,k都从0到30(因为3**30=205891132094649比小明的编号大)

这样我们就能找到所有符合规定的数,且我们用累加器n来记录大于小明编号的幸运数字

注意当i,j,k都为0时的那个数取不到,所以得出的答案要-1.


代码示例

n=0
for i in range(30):
    for j in range(30):
        for k in range(30):
            a=(3**i)*(5**j)*(7**k)
            b=(5**j)
            c=(7**k)
            if a<=59084709587506:
                n+=1
                

print(n-1)

二、组合型枚举

问题描述

排列与组合是常用的数学方法,其中组合就是从 n 个元素中抽出 m 个元素(不分顺序且 m≤n),我们可以简单地将 n 个元素理解为自然数1,2,…,n,从中任取 m个数。

现要求你输出所有组合。

输入格式

一行两个自然数 n,m(1<n<21,0≤m≤n).

输出格式

所有的组合。

输入示例

5 3

输出示例

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5


问题分析

用dfs来找所有的可能结果,对于n个数我们可以第一个开始往后看,对于每一个数可以选择他,也可以不选择他。若后面的路走不通进行回溯时记得“还原现场”。

check函数来帮我们看是否选了m个数,若足够了就输出;若选的数>m,或者已经选择的数加上后面剩余可以进行选择的数的个数<m,则进行剪枝。

C_{n}^{m}中的m=代码中的m1,n=代码中的n1。代码中的n,m两个累加器,n代表的是选中数的个数,m代表的是现在处理到第几个数(应该是m+1)


代码示例

n=0
m=0
def dfs():
    global n,m,n1,m1
    if not check():
        return
    else:
        for i in range(2):
            if i==0:
                n+=1
                lt.append(ls[m][0])
                m+=1
                dfs()
                m-=1
                n-=1
                del lt[-1]
            else:
                m+=1
                dfs()
                m-=1
def check():
    global n,m,n1,m1
    if n==m1:
        s=" ".join(lt)
        print(s)
        return False
    elif n>m1 or n+n1-m<m1:
        return  False
    else:
        return True

if __name__=="__main__":
    lt=[]
    n1,m1=map(int,input().split())
    ls=[(str(i),0) for i in range(1,n1+1)]

    dfs()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值