题解 | #素数伴侣#
素数伴侣
https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
import sys
from copy import deepcopy
from collections import defaultdict
# 生成素数列表
isprime = [1 for i in range(60001)]
# 匈牙利算法,先到先得能让就让
# 有机会上,没机会创造机会也要上
used = [] # 偶数是否使用过
# 奇偶分组
odd = []
even = []
evenForOdd = defaultdict(int)
def find(i):
for j in even:
if isprime[i + j] and used[j] == 0:
used[
j
] = 1 # 这个标志位表示当前i,j正在试图在一起,其他人别来打扰。没有这个标志位,每个人在递归的时候都会来询问,这样for循环就走不完了
# 判断j是否名花有主
if evenForOdd[j] == 0: # 这个偶数没有主(匹配奇数)
evenForOdd[j] = i # 赶紧占住
return True # 表示该奇数已经找到偶数,计数加一
else: # 名花有主
if find(evenForOdd[j]): # 能让则让
evenForOdd[j] = i # 这个坑归你了
return True
# else 下一个更好!
if __name__ == "__main__":
# 输入
n = int(input())
line = list(map(int, input().split()))
# isprime[2] = 1
i = 2
while i < 60001:
if isprime[i] == 1:
for j in range(i + i, 60001, i):
isprime[j] = 0
i += 1
for i in line:
if i % 2 == 0:
even.append(i)
else:
odd.append(i)
s = 0 # 计数
for i in odd:
used = [0 for i in range(60001)]
if find(i):
s += 1
print(s)
#回溯在测试数据多的时候会超时
# track = []
# # tracks = []
# res = 0
# used = [0 for i in range(30001)]
# def backtrack():
# global res
# if len(track) > res :
# res = len(track)
# for o in odd:
# if used[o] == 1:
# continue
# track.append(o)
# used[o] = 1
# for e in even:
# if used[e] == 1:
# continue
# if isprime[o+e] != 1:
# continue
# track.append(e)
# used[e] = 1
# backtrack()
# used[e] = 0
# track.pop()
# used[o] = 0
# track.pop()
# backtrack()
# print((res//2))
#二分图##匈牙利算法#
查看5道真题和解析
