第一行输入一个正偶数
代表数字个数。
第二行输入
个正整数
代表给定的数字。
输出一个整数,代表最多可以挑选出的“素数伴侣”的数量。
4 2 5 6 13
2
在这个样例中,
和
可以组成一对素数伴侣,
和
也可以组成一对素数伴侣。因此,最多可以挑选出
对素数伴侣。
4 1 2 2 2
1
在这个样例中,
只能使用一次,与任意一个
组合均是“素数伴侣”。
2 3 6
0
n = int(input()) s = list(map(int, input().split())) count = 0 i = 0 while i < n - 1: m = s[i] + s[i+1] if m == 2&nbs***bsp;m == 3: count += 1 i += 2 continue if m % 2 == 0: i += 1 continue is_prime = True for j in range(2, int(m**0.5)+1): if m % j == 0: is_prime = False break if is_prime: count += 1 i += 2 else: i += 1 print(count)
#!/user/local/bin/python3
import math
def is_prime(num): #判断是否是质数
if num<2:
return False
if num==2:
return True
pnum=int(math.sqrt(num))+1
for i in range(2,pnum):
if num%i==0:
return False
return True
def find_element(eles,target): ##查找元素在列表中第一次出现的索引,没有找到返回-1
for i in range(len(eles)):
if eles[i].count(target) > 0:
return i
return -1
def takeSecond(elem):
return elem[1]
strnumbs=int(input())
sources=list(map(int,input().split()))
#思路:除了2,所有的质数都是一个奇数+一个偶数,所以可以分成两个队列进行配对。
#双重循环,找出所有元素所有可能的配对情况,有一个配对加一分。按照分数,从低到高排序。所有可能的配对结果放在配对池子中。
#1.分数为0的元素不能配对,从分数排行榜中删除。
#2.优先满足分数少的元素形成配对,配对以后,配对结果放在成果池子中,配对结果从配对池子中删除,配对的两个元素的分数都减一。
#3.如果数字X放入成果池子中的次数等于X在原始列表中的数量(考虑X在原始列表中有重复的情况),清空配对池子中所有包含X的配对,将X的分数清零。
#刷新分数排行榜,重复上述(1)(2)(3)步骤,直到分数排行榜为空或配对池子为空。
#除了2,所有的质数都是一个奇数+一个偶数,所以可以分成两个队列
odd=[item for item in sources if item%2!=0] #奇数队列
even=[item for item in sources if item%2==0] #偶数队列
odd.sort()
even.sort()
final_result=[] #成果池子
backup_result=[] #配对池子
sourcelist=[[elem,0,0] for elem in sources] #分数排行榜,第二列代表配对分数,第三列代表是否已经放入成果池子
##初始化分数排行榜
for i in range(len(odd)):
for j in range(len(even)):
if is_prime(odd[i]+even[j]): ##找到配对
backup_result.append([odd[i],even[j]])
sourcelist[find_element(sourcelist,odd[i])][1]+=1
sourcelist[find_element(sourcelist,even[j])][1]+=1
sourcelist.sort(key=takeSecond)
i=0
while i < len(sourcelist) and len(backup_result)>0:
if sourcelist[i][1]==0:
sourcelist.pop(i) ##删除分数排行榜中无法配对的元素
continue
else:
while sourcelist[i][1]>0:
##找到第一个配对的元素的在配对池子中的索引
xindex=find_element(backup_result,sourcelist[i][0])
##找到第一个配对中另一个元素在分数排行榜中的索引
if sourcelist[i][0]%2==0:
another_index=find_element(sourcelist,backup_result[xindex][0])
else:
another_index=find_element(sourcelist,backup_result[xindex][1])
sourcelist[i][1]-=1 ##配对的第一个元素,分数减一
sourcelist[another_index][1]-=1 ##配对的第二个元素,分数减一
final_result.append(backup_result[xindex]) ##将配对结果放入成果池子中
sourcelist[i][2]=1 ##记录该元素放入成果池子中的次数
sourcelist[another_index][2]=1 ##记录该元素放入成果池子中的次数
backup_result.pop(xindex) ##删除配对池子中的该配对
#如果元素X放入成果池子中的次数等于X在原始列表中的数量(考虑X在原始列表中有重复的情况),清空配对池子中所有包含X的配对,将X的分数清零。
if sourcelist[i][2] == sources.count(sourcelist[i][0]):
while find_element(backup_result,sourcelist[i][0])!=-1:
popone=backup_result.pop(find_element(backup_result,sourcelist[i][0])) #清空配对池子中所有包含X的配对
find_index=find_element(sourcelist,popone[0]) ##清空配对的时候,对应的元素分数减一
sourcelist[find_index][1]-=1
find_index2=find_element(sourcelist,popone[1])
sourcelist[find_index2][1]-=1
sourcelist[i][1]=0 ##X的分数清零,不再参与配对
if sourcelist[another_index][2] == sources.count(sourcelist[another_index][0]):
while find_element(backup_result,sourcelist[another_index][0])!=-1:
popone=backup_result.pop(find_element(backup_result,sourcelist[another_index][0]))
find_index=find_element(sourcelist,popone[0])
sourcelist[find_index][1]-=1
find_index2=find_element(sourcelist,popone[1])
sourcelist[find_index2][1]-=1
sourcelist[another_index][1]=0
sourcelist.sort(key=takeSecond) #刷新分数排行榜
#print("Final Result:",final_result)
print(len(final_result))
# 最大匹配问题,尤其是在 二分图 中,通常不通过传统的动态规划方法来解决。相反,最大匹配问题更适合使用 图论算法,如 匈牙利算法 或 Hopcroft-Karp算法。 # 二分图匹配问题 import math # 判断一个数是否为素数 def is_prime(x): if x < 2: return False if x == 2: return True for i in range(3, int(math.sqrt(x)) + 1,2): if x % i == 0: return False return True # 匈牙利算法核心函数,尝试为偶数节点找到一个匹配的奇数节点 def bpm(u, graph, seen, match_to_V): for v in graph[u]: if not seen[v]: seen[v] = True # 如果奇数节点v未被匹配,或者可以为其找到其他匹配 if match_to_V[v] == -1&nbs***bsp;bpm(match_to_V[v], graph, seen, match_to_V): match_to_V[v] = u return True return False # 主函数,处理输入并寻找最大匹配对数 def max_prime_pairs(nums): # 将输入分为奇数和偶数 odds = [] evens = [] for num in nums: if num % 2 == 0: evens.append(num) else: odds.append(num) # 构建二分图的邻接表,graph[u] 存储偶数u能配对的奇数v的索引 graph = [[] for _ in range(len(evens))] for i, even in enumerate(evens): for j, odd in enumerate(odds): if is_prime(even + odd): graph[i].append(j) # 初始化匹配数组,-1表示未匹配 match_to_V = [-1] * len(odds) result = 0 # 对每个偶数节点尝试找到匹配 for u in range(len(evens)): seen = [False] * len(odds) if bpm(u, graph, seen, match_to_V): result += 1 return result # 读取输入 if __name__ == "__main__": import sys input = sys.stdin.read().split() ptr = 0 while ptr < len(input): if ptr >= len(input): break n = int(input[ptr]) ptr += 1 if ptr + n > len(input): break nums = list(map(int, input[ptr:ptr + n])) ptr += n # 调用函数并输出结果 print(max_prime_pairs(nums))
n = int(input())
arr = list(map(int, input().split()))
n1,n2 = [],[]
g = {}
st = [False]*30010
match = [0]*30010
res = 0
# 二分图的最大匹配数, 关键点在于点集的选取
def is_prime(num):
if num <= 1:
return False
for i in range(2, int(num**0.5) + 1):
if num % i == 0:
return False
return True
def find(x):
global g,match,st
for j in g[x]:
if not st[j]:
# 标记n2点已经被遍历过
st[j] = True
if match[j] == 0&nbs***bsp;find(match[j]):
match[j] = x
return True
return False
# 建图
for i in range(len(arr)):
for j in range(len(arr)):
if is_prime(arr[i] + arr[j]):
if arr[i] not in g.keys():
g[arr[i]] = [arr[j]]
else:
g[arr[i]].append(arr[j])
# 二分
for a in g.keys():
# 可以分为奇数与偶数
if a%2 == 1:
n1.append(a)
else:
n2.append(a)
# 匈牙利算法得最大值,将不能作为素数伴侣的点作为一边
for i in range(len(n1)):
# 每次遍历时初始化st数组为False;!!!st[j]存的是右半部分的节点j是否被访问过
st = [False]*30010
if find(n1[i]):
res+=1
print(res)
import sys """ 匈牙利算法:先到先得,能让则让 """ n=int(input()) data=list(map(int,input().split())) # print(data) def odd_is_prime(odd): """ 只可能奇数+偶数为素数,奇数+偶数又是奇数,所以只用判断奇数 """ for i in range(3,int(odd**0.5)+2,2): if odd%i==0: return False return True def matrix(odds,evens): """ 素数矩阵,能配对的置为1 """ l=[[0 for _ in evens] for _ in odds] for r,o in enumerate(odds): for c,e in enumerate(evens): if odd_is_prime(o+e): l[r][c]=1 return l def find(oi,evens,matrix,used_e,connect_e): """ 给奇数配对 """ for ei in range(len(evens)): # 可以配对,而且偶数没有被使用过 if matrix[oi][ei]==1 and used_e[ei]==0: used_e[ei]=1 # 标记一下,此偶数被使用了 # 如果偶数未被配对,或者 被配对的奇数还可以找到其他偶数配对 # connect_e[] 里放的是配对的奇数 if connect_e[ei]==-1&nbs***bsp;find(connect_e[ei],evens,matrix,used_e,connect_e): connect_e[ei]=oi return 1 return 0 odds=[] evens=[] # 奇偶分组 for e in data: if e%2==0: evens.append(e) else: odds.append(e) m=matrix(odds,evens) connect_e=[-1 for _ in evens] count=0 for oi in range(len(odds)): used_e=[0 for _ in evens] if find(oi,evens,m,used_e,connect_e): count+=1 print(count)
import math
n=int(input())
a=input().split(' ')
num=list(map(int,a))
od=list(filter(lambda x:x%2==1,num))
ev=list(filter(lambda x:x%2==0,num))
def check(num):
for i in range(2,int(math.sqrt(num)+2)):
if num%i==0:
return False
return True
s=[[0]*len(od) for i in range(len(ev))]
for i in range(len(ev)):
for j in range(len(od)):
if check(ev[i]+od[j]):
s[i][j]=1
aa=[]
def find(lodd,choose,evei,s,ss):
for j in range(lodd):
if s[evei][j]==1 and ss[j]==0:
ss[j]=1
if j not in choose&nbs***bsp;find(lodd,choose,choose.index(j),s,ss):
if evei>=len(choose):
choose.append(j)
else:
choose[evei]=j
return True
return False
con=0
for i in range(len(ev)):
ss=[0]*len(od)
if find(len(od),aa,i,s,ss):
con+=1
print(con)
from math import sqrt
def is_prime(x): # 判断素数
if x == 2:
return True
else:
for i in range(2,int(sqrt(x))+1):
if x % i == 0:
return False
return True
# 匈牙利算法 :用奇数挨个匹配偶数,偶数没有素数伴侣直接被匹配,有的话问问这个这个偶数当前的素数伴侣能不能让让
def f1(m:int,lr:list[list[int]],vis:list[int]):
for j in range(len(lr)):
if vis[j]==1:
continue
if is_prime(m+lr[j][0]):
vis[j] = 1 # 这里必须先吧vis[j] 置为1 不然容易死循环
if lr[j][1] == 0&nbs***bsp;f1(lr[j][1],lr,vis) :
lr[j][1] = m
return True
return False
n = int(input())
l = list(map(int,input().split(' ')))
ll = [] # 奇数列表
lr = [] # 偶数及其伴侣列表
for item in l:
if item % 2 == 0:
lr.append([item, 0]) # 第二位储存 当前偶数的素数伴侣
else:
ll.append(item)
count = 0
for item in ll:
vis = [0] * len(lr)
if f1(item,lr,vis):
count += 1
print(count)
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <math.h> #include <algorithm> #include <vector> using namespace std; vector<int> G[105]; bool flag[105]; int pre[105]; bool dfs(int k){ int x; for(int i=0;i<G[k].size();i++){ x=G[k][i]; if (flag[x]) continue; flag[x]=true; if((pre[x]==0)||dfs(pre[x])){ pre[x]=k; return true; } } return false; } bool isprime[80000]; int nums[105]; int main(){ memset(isprime,1,sizeof(isprime)); isprime[0]=isprime[1]=false; for(int i=4;i<80000;i+=2)isprime[i]=false; for(int i=3;i*i<80000;i+=2) if(isprime[i]){ for(int j=i*i;j<80000;j+=2*i) isprime[j]=false; } int n; while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ scanf("%d",&nums[i]); } for(int i=1;i<=n;++i){ for(int j=i+1;j<=n;++j){ if(isprime[nums[i]+nums[j]]){ (nums[i]&1)?G[i].push_back(j):G[j].push_back(i); } } } memset(pre,0,sizeof(pre)); int ans=0; for(int i=1;i<=n;i++){ memset(flag,false,sizeof(flag)); if (dfs(i)) ans++; } printf("%d\n",ans); for(int i=1;i<=n;++i){ G[i].clear(); } } return 0; }#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N=510; int n,m,x,y;vector<int>g[N]; namespace Blossom{ int mate[N],n,ret,nxt[N],f[N],mark[N],vis[N];queue<int>Q; int F(int x){return x==f[x]?x:f[x]=F(f[x]);} void merge(int a, int b){f[F(a)]=F(b);} int lca(int x, int y){ static int t=0;t++; for(;;swap(x,y)) if(~x){ if(vis[x=F(x)]==t) return x;vis[x]=t; x=mate[x]!=-1?nxt[mate[x]]:-1; } } void group(int a, int p){ for(int b,c;a!=p;merge(a,b),merge(b,c),a=c){ b=mate[a],c=nxt[b]; if(F(c)!=p)nxt[c]=b; if(mark[b]==2)mark[b]=1,Q.push(b); if(mark[c]==2)mark[c]=1,Q.push(c); } } void aug(int s, const vector<int>G[]){ for(int i=0;i<n;++i)nxt[i]=vis[i]=-1,f[i]=i,mark[i]=0; while(!Q.empty())Q.pop();Q.push(s);mark[s]=1; while(mate[s]==-1&&!Q.empty()){ int x=Q.front();Q.pop(); for(int i=0,y;i<(int)G[x].size();++i){ if((y=G[x][i])!=mate[x]&&F(x)!=F(y)&&mark[y]!=2){ if(mark[y]==1){ int p=lca(x,y); if(F(x)!=p)nxt[x]=y; if(F(y)!=p)nxt[y]=x; group(x,p),group(y,p); }else if(mate[y]==-1){ nxt[y]=x; for(int j=y,k,l;~j;j=l)k=nxt[j],l=mate[k],mate[j]=k,mate[k]=j; break; }else nxt[y]=x,Q.push(mate[y]),mark[mate[y]]=1,mark[y]=2; } } } } int solve(int _n, const vector<int>G[]){ n=_n;memset(mate, -1, sizeof mate); for(int i=0;i<n;++i) if(mate[i]==-1)aug(i,G); for(int i=ret=0;i<n;++i)ret+=mate[i]>i; printf("%d\n",ret); //for(int i=0;i<n;i++)printf("%d %d\n",i+1,mate[i]+1); return ret; } } bool isprime[80000]; int nums[105]; int main(){ memset(isprime,1,sizeof(isprime)); isprime[0]=isprime[1]=false; for(int i=4;i<80000;i+=2)isprime[i]=false; for(int i=3;i*i<80000;i+=2) if(isprime[i]){ for(int j=i*i;j<80000;j+=2*i) isprime[j]=false; } while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ scanf("%d",&nums[i]); } for(int i=0;i<n;++i){ for(int j=i+1;j<n;++j){ if(isprime[nums[i]+nums[j]]){ g[i].push_back(j); g[j].push_back(i); } } } Blossom::solve(n,g); for(int i=0;i<n;++i){ g[i].clear(); } } }