题意:
定义一种集合,只有两个数,两个数不同且加起来为素数。要从n个数里抽出数字组成该集合(数字也可以是1~n,这个好懵圈啊),要求你选择最多k个该种集合组成一个有最多元素的集合,求出元素的数量。
思路:
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; const int maxn=3000+10; const int masn=2e6+10; int n,m,ans,head[maxn],p[maxn],a[maxn]; bool vis[maxn],prime[masn]; vector<int> g[maxn]; bool slove(int x) { vis[x]=true; int len=g[x].size(); for(int i=0;i<len;i++) { int v=g[x][i]; if(!vis[v]) { vis[v]=true; if(a[v]==0||slove(a[v])) { a[v]=x; a[x]=v; return true; } } } return false; } int main() { for(int i=2;i<masn;i++) if(!prime[i]) for(int j=i+i;j<masn;j+=i) prime[j]=true; void add_(int,int); bool slove(int); int t; cin>>t; while(t--) { ans=1; memset(head,-1,sizeof(head)); cin>>n>>m; for(int i=1;i<=n;i++) { cin>>p[i]; g[i].clear(); } memset(a,-1,sizeof(a)); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(!prime[p[i]+p[j]]) { g[i].push_back(j); g[j].push_back(i); a[i]=a[j]=0; } int sumn=0,summ=0; for(int i=1;i<=n;i++) if(a[i]==0) { memset(vis,false,sizeof(vis)); if(slove(i)) sumn++; } for(int i=1;i<=n;i++) if(a[i]==0) summ++; if(sumn>=m) cout<< 2*m <<endl; else { int w=m-sumn; cout<< sumn*2+min(w,summ) <<endl; } } return 0; }