题目描述
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。
输入格式
第1行为两个正整数n,sum
输出格式
一个1~N的一个排列
样例输入
4 16
样例输出
3 1 2 4
数据规模和约定
0<n<=10
思路分析
利用内置的itertools.permutations更加方便,从排列入手,反推求和,按字典顺序遍历即可,但是只得到60分--程序1
改进:利用生成器,每次生成一种排列,极大节省内存,90分--程序2
关键函数
def generate_permutations(elements):
if len(elements) == 0:
yield []
else:
for i in range(len(elements)):
rest = elements[:i] + elements[i+1:]
for p in generate_permutations(rest):
yield [elements[i]] + p
完整代码
# 试题 算法训练 数字游戏 程序1
from itertools import permutations as per
def calcu(li: list)->int:
while len(li) > 1:
temp = []
for i in range(len(li) - 1):
temp.append(li[i] + li[i+1])
li = temp
return li.pop()
def main():
n, sum_ = list(map(int, input().rstrip().split()))
li_all = list(per(range(1, 1+n)))
for li in li_all:
if calcu(li=list(li)) == sum_:
print(*li)
break
if __name__ == "__main__":
main()
# 试题 算法训练 数字游戏 程序2
from itertools import permutations as per
def generate_permutations(elements):
if len(elements) == 0:
yield []
else:
for i in range(len(elements)):
rest = elements[:i] + elements[i+1:]
for p in generate_permutations(rest):
yield [elements[i]] + p
def calcu(li: list)->int:
while len(li) > 1:
temp = []
for i in range(len(li) - 1):
temp.append(li[i] + li[i+1])
li = temp
return li.pop()
def main():
n, sum_ = list(map(int, input().rstrip().split()))
# li_all = list(per(range(1, 1+n)))
li_ = generate_permutations(list(range(1, 1+n)))
for li in li_:
if calcu(li=list(li)) == sum_:
print(*li)
break
if __name__ == "__main__":
main()
运行结果
请读者合理引用,转载文章内容,部分内容参考自网络,如有侵权联系删除