回溯算法——素数环、全排列

素数环

"""
# @Time    :  2020/11/25
# @Author  :  Jimou Chen
"""
from math import sqrt

n = int(input())
num = [0 for _ in range(n + 1)]
flag = [0 for _ in range(n + 1)]


# 判断素数
def prime(x):
    for i in range(2, int(sqrt(x)) + 1):
        if x % i == 0:
            return 0

    return 1


# x 是当前的数,v是满足条件的前一个数
def dfs(x, v):
    if x == n + 1:
        # 判断最后一个数和第一个数之和
        if prime(v + 1):
            for i in range(1, n + 1):
                print(num[i], end=' ')
            print()
            return  # return的位置是和for同一级的

    for i in range(1, n + 1):
        if flag[i] == 0 and prime(i + v):
            flag[i] = 1
            num[x] = i
            dfs(x + 1, i)
            flag[i] = 0


num[1] = 1
flag[1] = 1
dfs(2, 1)

'''
6
1 4 3 2 5 6 
1 6 5 2 3 4 


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 
'''

优化

  • 把素数判断用素数表标志存储,提高效率

'''
优化的话,可以使用素数表,这样就不用每次都遍历判断了
'''
k = 0
# 素数表,1表示素数
def prime_table(x):
    global k
    l = [1 for _ in range(x + 1)]
    for i in range(2, x + 1):
        for k in range(2, int(sqrt(i)) + 1):
            if i % k == 0:
                l[i] = 0

    return l

prime = prime_table(n+100)

另一种写法

from math import sqrt

def isPrime(num):
    for i in range(2, int(sqrt(num)) + 1):
        if num % i == 0:
            return 0
    return 1

def isPrimeCircle(box):
    if box[0] != 1:
        return 0
    box.append(box[0])
    for i in range(len(box) - 1):
        if isPrime(box[i] + box[i+1]) == 0:
            box.pop()
            return 0
    box.pop()
    return 1
    
def backtrack(nums, box):
    if (len(box) == len(nums)) and (isPrimeCircle(box) == 1):
        print(box)        
        return

    for i in nums:
        if i in box:
            continue

        box.append(i)
        backtrack(nums, box)
        box.pop()


while True:
    try:
        n = int(input())
        b = []
        test = [_ + 1 for _ in range(n)]
        backtrack(test, b)
    except:
        break

全排列

posted @ 2020-11-26 00:21  JackpotNeaya  阅读(230)  评论(0)    收藏  举报