【蓝桥杯】省赛无忧班(Python 组)第 2 期 11.1搜索

#1.
from numpy import w

x, n = map(int, input().split())
# 记录每层选择数字
a = [0] * n
# 计算次数:cnt
cnt = 0

def dfs(depth):
    """
    :param depth:当前为第几重循环
    :return:
    """
    global cnt
    cnt += 1
    # 第0重-第n-1重都已经选好数字,此时只需要判断答案
    if depth == n:
        # 条件一:数字需要递增
        for i in range(1, n):
            if a[i] >= a[i - 1]:
                continue
            else:
                return
        # 条件二:数字和为X
        if sum(a) != x:
            return
        # 此时是答案
        print(a)
        return
    # 第depth层进行选择数字:[1,x]进行枚举
    for i in range(1, x + 1):
        # 选择第depth层的数字
        a[depth] = i
        # 递归进入下一层
        dfs(depth + 1)

dfs(0)
print("累计计算次数={}".format(cnt))
'''
这段代码的功能是解决一个组合问题。给定两个整数x和n,要求在1到x之间选择n个数,使得这n个数满足以下条件:
1. 数字需要递增;
2. 数字和为x。
代码通过深度优先搜索(DFS)算法实现,首先定义了一个全局变量cnt用于记录计算次数。
然后定义了一个递归函数dfs,参数depth表示当前为第几重循环。
在函数内部,首先判断是否已经选好了所有的数字,如果是,则判断这些数字是否满足条件一和条件二,如果满足,则输出结果。
如果不满足条件一或条件二,则返回。接下来,对第depth层的数字进行枚举,选择一个数字后,递归进入下一层。
最后,调用dfs(0)开始搜索,并输出累计计算次数。
'''

#2.
'''
这段代码是一个深度优先搜索(DFS)算法的实现,用于解决一个组合问题。给定两个整数n和x,要求在1到x之间选择n个数,使得这n个数满足以下条件:
1. 数字需要递增;
2. 数字和为x。
代码中的dfs函数是一个递归函数,参数depth表示当前是第几重循环,last_val表示上一层选择的数字。
函数首先判断是否已经选好了所有的数字,如果是,则判断这些数字的和是否等于x,如果不等于x,则返回;如果等于x,则输出这些数字。
接下来,函数对第depth层的数字进行枚举,选择满足条件的数字,并递归进入下一层。最后,调用dfs(0, 1)开始搜索。
'''
def dfs(depth, last_val):
    '''
    :param depth:当前为第几重循环
    :return:
    '''
    global cnt
    cnt = cnt + 1
    # 第0重-第n-1重都已经选好数字,此时只需要判断答案
    if depth == n:
        # 条件二:数字和为x
        if sum(a) != x:
            return
        # 此时是答案
        print(a)
        return
    # 第depth层进行选择数字:[1,x]进行枚举
    # 条件一:数字需要递增
    for i in range(last_val, x + 1):
        # 选择第depth层的数字
        a[depth] = i
        # 递归进入下一层
        dfs(depth + 1, i)

dfs(0, 1)

#3.模板
def dfs(depth) :
'''
:param depth: :
当前为第几重循环
:return:
'''

if depth == N:
#N重循环最内层执行的代码
    return
#每重循环进行的枚举选择

#4.分糖果
# 定义一个全局变量ans,用于记录满足条件的分配方案数
ans = 0

# 定义一个dfs函数,参数为depth(当前小朋友的编号)、n(第一类糖果的数量)和m(第二类糖果的数量)
def dfs(depth, n, m):
    # 如果当前小朋友的编号为7,且两种糖果都分配完毕,则将ans加1,并返回
    if depth == 7:
        if n == 0 and m == 0:
            global ans
            ans += 1
            return
    # 对于每个小朋友,枚举第一种糖果的数量i(0到5),枚举第二种糖果的数量j(0到5)
    for i in range(0, 6):
        # 枚举第二种糖果
        for j in range(0, 6):
            # 如果i+j在2到5之间,且i不超过n,j不超过m,则递归调用dfs函数,继续分配剩余的糖果
            if 2 <= i + j <= 5 and i <= n and j <= m:
                dfs(depth + 1, n - i, m - j)

# 调用dfs(0, 9, 16)开始搜索
dfs(0, 9, 16)
# 打印结果ans
print(ans)
#5.买瓜
'''
这段代码是一个深度优先搜索(DFS)算法的实现,用于解决一个劈西瓜的问题。给定一个西瓜的重量列表w和目标重量m,要求找出最少需要劈多少个西瓜才能达到目标重量。
解析:
1. 定义一个递归函数dfs,参数为depth(当前层数)、s(当前累计重量)和cnt(当前劈的西瓜个数)。
2. 递归出口:
   - 如果当前累计重量已经超过m,不需要继续下去。
   - 如果当前累计重量等于m,直接更新答案。
   - 如果当前层数等于n,停止继续递归。
3. 在第depth层时,有三种选择:买一个、买半个、不买。分别对应三种情况调用dfs函数。
4. 初始化变量n、m、W和ans。
5. 调用dfs函数,从第0层开始搜索。
6. 如果找到答案,输出ans;否则输出-1。
'''
def dfs(depth, s, cnt):
    global ans  # 声明全局变量ans
    # 递归出口
    if s > m:  # 如果当前累计重量已经超过m,不需要继续下去
        return
    if s == m:  # 如果当前累计重量等于m,直接更新答案
        ans = min(ans, cnt)
    if depth == n:  # 如果当前层数等于n,停止继续递归
        return
    # 在第depth层时,有三种选择:买一个、买半个、不买。分别对应三种情况调用dfs函数。
    # 买一个
    dfs(depth + 1, s + w[depth], cnt)
    # 买半个
    dfs(depth + 1, s + w[depth] // 2, cnt + 1)
    # 不买
    dfs(depth + 1, s, cnt)

n, m = map(int, input().split())  # 输入西瓜的数量n和目标重量m
W = list(map(int, input().split()))  # 输入每个西瓜的重量列表W
W = [x * 2 for x in W]  # 将每个西瓜的重量乘以2,因为可以买半个
ans = float('inf')  # 初始化答案为正无穷,表示还没有找到满足条件的答案
dfs(0, 0, 0)  # 从第0层开始搜索,初始累计重量为0,劈的西瓜个数为0
if ans == float('inf'):  # 如果答案仍然是正无穷,说明没有找到满足条件的答案
    ans = -1
print(ans)  # 输出答案#1.
from numpy import w

x, n = map(int, input().split())
# 记录每层选择数字
a = [0] * n
# 计算次数:cnt
cnt = 0

def dfs(depth):
    """
    :param depth:当前为第几重循环
    :return:
    """
    global cnt
    cnt += 1
    # 第0重-第n-1重都已经选好数字,此时只需要判断答案
    if depth == n:
        # 条件一:数字需要递增
        for i in range(1, n):
            if a[i] >= a[i - 1]:
                continue
            else:
                return
        # 条件二:数字和为X
        if sum(a) != x:
            return
        # 此时是答案
        print(a)
        return
    # 第depth层进行选择数字:[1,x]进行枚举
    for i in range(1, x + 1):
        # 选择第depth层的数字
        a[depth] = i
        # 递归进入下一层
        dfs(depth + 1)

dfs(0)
print("累计计算次数={}".format(cnt))
'''
这段代码的功能是解决一个组合问题。给定两个整数x和n,要求在1到x之间选择n个数,使得这n个数满足以下条件:
1. 数字需要递增;
2. 数字和为x。
代码通过深度优先搜索(DFS)算法实现,首先定义了一个全局变量cnt用于记录计算次数。
然后定义了一个递归函数dfs,参数depth表示当前为第几重循环。
在函数内部,首先判断是否已经选好了所有的数字,如果是,则判断这些数字是否满足条件一和条件二,如果满足,则输出结果。
如果不满足条件一或条件二,则返回。接下来,对第depth层的数字进行枚举,选择一个数字后,递归进入下一层。
最后,调用dfs(0)开始搜索,并输出累计计算次数。
'''

#2.
'''
这段代码是一个深度优先搜索(DFS)算法的实现,用于解决一个组合问题。给定两个整数n和x,要求在1到x之间选择n个数,使得这n个数满足以下条件:
1. 数字需要递增;
2. 数字和为x。
代码中的dfs函数是一个递归函数,参数depth表示当前是第几重循环,last_val表示上一层选择的数字。
函数首先判断是否已经选好了所有的数字,如果是,则判断这些数字的和是否等于x,如果不等于x,则返回;如果等于x,则输出这些数字。
接下来,函数对第depth层的数字进行枚举,选择满足条件的数字,并递归进入下一层。最后,调用dfs(0, 1)开始搜索。
'''
def dfs(depth, last_val):
    '''
    :param depth:当前为第几重循环
    :return:
    '''
    global cnt
    cnt = cnt + 1
    # 第0重-第n-1重都已经选好数字,此时只需要判断答案
    if depth == n:
        # 条件二:数字和为x
        if sum(a) != x:
            return
        # 此时是答案
        print(a)
        return
    # 第depth层进行选择数字:[1,x]进行枚举
    # 条件一:数字需要递增
    for i in range(last_val, x + 1):
        # 选择第depth层的数字
        a[depth] = i
        # 递归进入下一层
        dfs(depth + 1, i)

dfs(0, 1)

#3.模板
def dfs(depth) :
'''
:param depth: :
当前为第几重循环
:return:
'''

if depth == N:
#N重循环最内层执行的代码
    return
#每重循环进行的枚举选择

#4.分糖果
# 定义一个全局变量ans,用于记录满足条件的分配方案数
ans = 0

# 定义一个dfs函数,参数为depth(当前小朋友的编号)、n(第一类糖果的数量)和m(第二类糖果的数量)
def dfs(depth, n, m):
    # 如果当前小朋友的编号为7,且两种糖果都分配完毕,则将ans加1,并返回
    if depth == 7:
        if n == 0 and m == 0:
            global ans
            ans += 1
            return
    # 对于每个小朋友,枚举第一种糖果的数量i(0到5),枚举第二种糖果的数量j(0到5)
    for i in range(0, 6):
        # 枚举第二种糖果
        for j in range(0, 6):
            # 如果i+j在2到5之间,且i不超过n,j不超过m,则递归调用dfs函数,继续分配剩余的糖果
            if 2 <= i + j <= 5 and i <= n and j <= m:
                dfs(depth + 1, n - i, m - j)

# 调用dfs(0, 9, 16)开始搜索
dfs(0, 9, 16)
# 打印结果ans
print(ans)
#5.买瓜
'''
这段代码是一个深度优先搜索(DFS)算法的实现,用于解决一个劈西瓜的问题。给定一个西瓜的重量列表w和目标重量m,要求找出最少需要劈多少个西瓜才能达到目标重量。
解析:
1. 定义一个递归函数dfs,参数为depth(当前层数)、s(当前累计重量)和cnt(当前劈的西瓜个数)。
2. 递归出口:
   - 如果当前累计重量已经超过m,不需要继续下去。
   - 如果当前累计重量等于m,直接更新答案。
   - 如果当前层数等于n,停止继续递归。
3. 在第depth层时,有三种选择:买一个、买半个、不买。分别对应三种情况调用dfs函数。
4. 初始化变量n、m、W和ans。
5. 调用dfs函数,从第0层开始搜索。
6. 如果找到答案,输出ans;否则输出-1。
'''
def dfs(depth, s, cnt):
    global ans  # 声明全局变量ans
    # 递归出口
    if s > m:  # 如果当前累计重量已经超过m,不需要继续下去
        return
    if s == m:  # 如果当前累计重量等于m,直接更新答案
        ans = min(ans, cnt)
    if depth == n:  # 如果当前层数等于n,停止继续递归
        return
    # 在第depth层时,有三种选择:买一个、买半个、不买。分别对应三种情况调用dfs函数。
    # 买一个
    dfs(depth + 1, s + w[depth], cnt)
    # 买半个
    dfs(depth + 1, s + w[depth] // 2, cnt + 1)
    # 不买
    dfs(depth + 1, s, cnt)

n, m = map(int, input().split())  # 输入西瓜的数量n和目标重量m
W = list(map(int, input().split()))  # 输入每个西瓜的重量列表W
W = [x * 2 for x in W]  # 将每个西瓜的重量乘以2,因为可以买半个
ans = float('inf')  # 初始化答案为正无穷,表示还没有找到满足条件的答案
dfs(0, 0, 0)  # 从第0层开始搜索,初始累计重量为0,劈的西瓜个数为0
if ans == float('inf'):  # 如果答案仍然是正无穷,说明没有找到满足条件的答案
    ans = -1
print(ans)  # 输出答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值