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)