题意:
方法一:
匈牙利算法求最大匹配
思路:题目的意思是叫求最大匹配。然后,构造二分图,因为题目中输入的数据大小满足,所以最小的两数之和为4。因此素数的最小值为5,所以素数要满足奇数的条件。因此,可以将输入数据分为奇数和偶数两部分,构造二分图;如果奇数部分和偶数部分各取一个数相加的和是素数,则说明两个数之间存在一条边。最后,利用匈牙利算法即可解得最大匹配数量。
#include <bits/stdc++.h> using namespace std; int a[105]; int b[105];//奇数 int c[105];//偶数 int vis[30005]; int match[30005]; int n1,n2; int isPrime(int x){//判断是否是素数 if(x<=1) return 0; for(int i=2;i*i<=x;i++){ if(x%i==0) return 0; } return 1; } int Find(int x){//匈牙利算法 for(int i=0;i<n2;i++){ if(isPrime(x+c[i])){//遍历相连的边 int y=c[i]; if(vis[y]==0){//如果未被访问,则访问 vis[y]=1; if(match[y]==0||Find(match[y])){//如果未被匹配或已被匹配但匹配的对方可以换一个对象,则成功 match[y]=x; return 1; } } } } return 0; } int main(){ int n; while(cin >> n){ memset(match,0,sizeof(match)); int res=0; n1=0; n2=0; for(int i=0;i<n;i++){ cin >> a[i]; if(a[i]%2)//构造二分图 b[n1++]=a[i];//奇数数组 else c[n2++]=a[i];//偶数数组 } for(int i=0;i<n1;i++){//匈牙利算法寻找二分图的最大匹配 memset(vis,0,sizeof(vis)); if(Find(b[i]))//如果匹配成功,则结果加一 res++; } cout << res << endl; } return 0; }
时间复杂度:空间复杂度:
方法二:
素数优化+set
思路:首先,打素数表,可以用欧拉线性筛获得素数表。后面,将素数表存储在无序set中,之后就可以直接O(1)时间复杂度判断是否是素数。
#include <bits/stdc++.h> using namespace std; int a[105]; int prime[60005];//存储素数 int isPrime[60005];//判断是否是素数 int cnt=0; unordered_set<int> st; int b[105];//奇数 int c[105];//偶数 int vis[30005]; int match[30005]; int n1,n2; int Find(int x){//匈牙利算法 for(int i=0;i<n2;i++){ if(st.count(x+c[i])){//遍历相连的边 int y=c[i]; if(vis[y]==0){//如果未被访问,则访问 vis[y]=1; if(match[y]==0||Find(match[y])){//如果未被匹配或已被匹配但匹配的对方可以换一个对象,则成功 match[y]=x; return 1; } } } } return 0; } int main(){ for(int i=2;i<=60000;i++){//线性筛素数 打素数表 if(isPrime[i]==0)//默认0表示素数 prime[cnt++]=i;//添加素数 for(int j=0;j<cnt&&i<=60000/prime[j];j++){ isPrime[prime[j]*i]=1; if(i%prime[j]==0) break; } } for(int i=0;i<cnt;i++) st.insert(prime[i]); int n; while(cin >> n){ memset(match,0,sizeof(match)); int res=0; n1=0; n2=0; for(int i=0;i<n;i++){ cin >> a[i]; if(a[i]%2)//构造二分图 b[n1++]=a[i];//奇数数组 else c[n2++]=a[i];//偶数数组 } for(int i=0;i<n1;i++){//匈牙利算法寻找二分图的最大匹配 memset(vis,0,sizeof(vis)); if(Find(b[i]))//如果匹配成功,则结果加一 res++; } cout << res << endl; } return 0; }
时间复杂度:空间复杂度: