【问题描述】设计一个程序,使其将由1到N(N为偶数,且N <= 20)的N个正整数分别放置在由N个节点组成的环的各个节点上,其中1必须放在第一个节点上,并使任意两个相邻的节点上的数字之和为质数。要求最后一个数和开头第一个数(即1)之和也为质数。
下图是当N为6时的一个例。当N为6时的输出样例如下:
1 4 3 2 5 6
1 6 5 2 3 4
【输入形式】程序从标准输入上读入一个偶数。
【输出形式】在标准输出上打印所有符合要求的排列方法。
输出有若干行,每一行都是符合题意的一种排列方法,所有数字从1所在位置开始,按顺时针方向依次输出,各个数字之间以空格分隔。
各行上的排列方式不重复。
注意:输出各行遵循小数优先原则, 在各种排列方式中,较小的数尽量靠前输出。如果将每行上的输出看成一个数字,则所有输出构成升序数列。具体格式见输出样例。
【样例输入】
8
【样例输出】
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
【样例说明】输入整数8,要求将1、2、......、8排成环且相邻两数之和为素数。
合法的排列方法共有4种,由运行结果可见,第2位上可能的数字只有2、4和6。且先输出2开头的所有合法排列,再输出4开头的所有合法排列,最后输出6开头的所有合法排列,余下部分同样遵循此原则。
【运行时限】要求每次运行时间限制在20秒之内。超出该时间则认为程序错误。
提示:当N增大时,运行时间将急剧增加。在编程时要注意尽量优化算法,提高运行效率。
【评分标准】该题要求输出若干行整数。如果你的程序计算的结果和标准答案完全一致,则该测试点得满分,否则该测试点得分为0。
参考代码:
"""
Created on Mon Nov 10 14:33:39 2018
@author: Dina
"""
N = int(input())
flag = [0 for x in range(N+1)] # 标志列表,用于标识每个数是否放入到列表中,初始值都为 0
num_list = [0 for x in range(N+1)] # 用于存储数字环的列表,设置初始值都为 0
#--- 判断 num 是否是质数
def Isprime(num):
for i in range(2,num):
if (num % i ==0):
return False
return True
def DigitalRing(cur):
# 如果最后一个数放进去了,且最后一个数和第一个的和为质数,
# 且第一个数是1,就可以打印 num_list 列表里的数字了
if cur == N+1 and Isprime(num_list[1]+num_list[N]) and num_list[1] == 1:
# 从列表的下标为 1 的开始打印
for i in range(1,N+1):
print(num_list[i],end=' ')
print()
else:
# 尝试把每个数 i 放入到 num_list 中
for i in range(1,N+1):
# 若 i 还没有放入到 num_list 列表中,且与前一个数的和是质数
if flag[i]==0 and Isprime(i + num_list[cur -1]):
# 将这个数加入到放入到 num_list 列表中
num_list[cur] =i
# 标明这个数已放入到 num_list 列表中
flag[i] = 1
# 求下一个数
DigitalRing(cur+1)
# 将这个数的 flag 设置为 0 下一次就可以再使用了
flag[i] = 0
# 数字环从 1 开始
DigitalRing(1)
提交可通过: