P2089 烤鸡、P1706 全排列问题、P1157 组合的输出、P1036 [NOIP2002 普及组] 选数——Python代码实现(带注释)

文章讲述了使用深度优先搜索算法解决配料组合问题,找出所有可能的配料搭配以达到特定美味程度,同时介绍了全排列问题的解决方案,以及如何计算满足条件的素数组合数。
摘要由CSDN通过智能技术生成

P2089 烤鸡

题目背景

猪猪 Hanke 得到了一只鸡。

题目描述

猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 1010 种配料(芥末、孜然等),每种配料可以放 11 到 33 克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 n ,请输出这 1010 种配料的所有搭配方案。

输入格式

一个正整数 �n,表示美味程度。

输出格式

第一行,方案总数。

第二行至结束,1010 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 00。

输入输出样例

输入 #

11

输出 #

10
1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 2 1 
1 1 1 1 1 1 1 2 1 1 
1 1 1 1 1 1 2 1 1 1 
1 1 1 1 1 2 1 1 1 1 
1 1 1 1 2 1 1 1 1 1 
1 1 1 2 1 1 1 1 1 1 
1 1 2 1 1 1 1 1 1 1 
1 2 1 1 1 1 1 1 1 1 
2 1 1 1 1 1 1 1 1 1 

说明/提示

对于 100%100% 的数据,≤5000n≤5000。

n=int(input())
result=[]  #保存最终遍历的结果
sum_result=0 #记录方法的数量
tem_result=[0]*10  #列表用于保存各种配料之间用量记录
def dfs(x,zh):
      global sum_result,result
      if x>10: #如果十种配料已经称重完成,则继续判断十种配料的质量是否等于输入的重量
            if zh==n: #如果当前各种配料总合的质量为n
                  sum_result+=1
                  result.append(tem_result[:])
            return
      if zh>n: #如果总合大于输入的总合就结束遍历,即剪枝
            return
      
      for i in range(1,4):
            tem_result[x-1]=i
            dfs(x+1,zh+i)

def main():
      if 31>n>9:
            dfs(1,0)
            print(sum_result)
            for i in result:
                  for number in i:
                        print(number,end=" ")
                  print()
      else:
          print(0)  
main()

      


P1706 全排列问题

目描述

按照字典序输出自然数 11 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 n。

输出格式

由 1∼1∼n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 55 个场宽。

输入输出样例

输入 #1复制

3

输出 #1复制

    1    2    3
    1    3    2
    2    1    3
    2    3    1
    3    1    2
    3    2    1

说明/提示

1≤n≤9。

n=int(input())
st=[0]*(n+1) #st列表用于保存排列过程中当前位置是否被选择
res=[0]*(n+1)
def dfs(x):
    if x>n: #表示当递归的位数大于输入规定的位数,就结束递归
        for i in res:
            if i:
                print("{:5}".format(i),end="")
        print()
        return
    for i in range(1,n+1):
        if not st[i]: #注意事项:当前状态列表的索引为i,表示检查当前位置为空,就继续下一步操作
            st[i]=1 #表示当前对第i位进行赋值,需要注意的是状态列表的索引为i。表示对第i位操作
            res[x]=i
            dfs(x+1) #进行下一次遍历
            st[i]=0
            res[x]=0

dfs(1)
    

P1157 组合的输出

题目描述

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

现要求你输出所有组合。

例如 n=5,r=3,所有组合为:

123,124,125,134,135,145,234,235,245,345123,124,125,134,135,145,234,235,245,345。

输入格式

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

输出格式

所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。

注意哦!输出时,每个数字需要 33 个场宽。以 C++ 为例,你可以使用下列代码:

cout << setw(3) << x;

输出占 33 个场宽的数 x。注意你需要头文件 iomanip

输入输出样例

输入 #1复制

5 3 

输出 #1复制

  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

list_var=list(map(int,input().split())) #完成程序参数的输入
n,r=list_var[0],list_var[1]  #将用户输入的数据保存到指定的变量中
res=[0]*(r+1)  #定义一个结果列表,将深度遍历搜索得到的结果进行保存

def dfs(x,start):
    if x>r: #结束遍历标志,当遍历的位数大于用户指定的位数就停止便利
        for i in res: #输出结果
            if i :
                print("{:3}".format(i),end="")
        print()
        return
    for i in range(start,n+1): #因为是组合问题,所以用过的参数就不能再使用了,因此从start开始寻找数字
        res[x]=i #将未使用的数字保存到结果列表中
        dfs(x+1,i+1) #函数递归调用
        res[x]=0 #回溯

dfs(1,1)

P1036 [NOIP2002 普及组] 选数

题目描述

已知 n 个整数 1,2,⋯ ,x1​,x2​,⋯,xn​,以及 11 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,44 个整数分别为 3,7,12,193,7,12,19 时,可得全部的组合与它们的和为:

3+7+12=223+7+12=22

3+7+19=293+7+19=29

7+12+19=387+12+19=38

3+12+19=343+12+19=34

现在,要求你计算出和为素数共有多少种。

例如上例,只有一种的和为素数:3+7+19=293+7+19=29。

输入格式

第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。

第二行 n 个整数,分别为 x1​,x2​,⋯,xn​(1≤xi​≤5×106)。

输出格式

输出一个整数,表示种类数。

输入输出样例

输入 #1复制

4 3
3 7 12 19

输出 #1复制

1
list_number=list(map(int,input().split())) #将用户外部输入的两个数据进行保存
n,k=list_number[0],list_number[1] #将用户输入的数据按照题目要求,分别赋值给n,k两个变量
list_input=list(map(int,input().split())) #接收用户输入的列表
res=[0]*(k+1) #保存完成一次DFS的结果
count=0 #保存当前的求和结果为素数的个数

def judje_sushu(number): #判断素数
    for i in range(2,number):
        if number%i==0:
            return 0
    return 1
    

def dfs(x,start):
    global count #在函数中引用全局变量的时候,需要使用关键字global进行声明
    if x>k:
        result=[] #保存一次便利结束后的数据,便于求和判断素数
        for i in res:
            if i:
                result.append(i) #保存便利数据到result中
        sum_res=sum(result) #求和结果
        if judje_sushu(sum_res): #判断求和结果是否为素数,如果是素数就将count的值加一
            count+=1
        return
    for i  in range(start,len(list_input)): #按顺序提取用户给出的数据
        res[x]=list_input[i] #将提取到的保存res列表中
        dfs(x+1,i+1) #调用dfs函数实现深度优先搜索
        res[x]=0 #回溯

dfs(1,0)
print(count)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值