描述
题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。
输出:
输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。
输入描述:
输入说明
1 输入一个正偶数n
2 输入n个整数
注意:数据可能有多组
输出描述:
求得的“最佳方案”组成“素数伴侣”的对数。
示例1
输入:
4
2 5 6 13
2
3 6
复制输出:
2
0
第一次写匈牙利算法,就是遍历二分图A集合的每一个节点,与B的匹配情况,如B某个点已经匹配,再往下搜。
参考:https://blog.youkuaiyun.com/qq_38956769/article/details/80238896
https://blog.youkuaiyun.com/qq_46105170/article/details/113830924
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) {new Main().run();}
FastReader in = new FastReader();
PrintWriter out = new PrintWriter(System.out);
void run(){
rec=new boolean[60002];
for(int i=2;i*i<60002;i++){
if(!rec[i]){
for(int j=i;j*i<60002;j++){
rec[i*j]=true;
}
}
}
while(in.hasNext())
work();
out.flush();
}
long mod=998244353;
long gcd(long a,long b) {
return a==0?b:gcd(b%a,a);
}
final long inf=Long.MAX_VALUE/3;
ArrayList<Integer>[] graph;
int n;
int[] match;
boolean[] rec;
int[] A;
int[] color;
void work(){
this.n=ni();
match=new int[n];
Arrays.fill(match,-1);
graph=(ArrayList<Integer>[])new ArrayList[n];
for(int i=0;i<n;i++){
graph[i]=new ArrayList<>();
}
A=nia(n);
color=new int[n];
for(int i=0;i<n;i++){
if(A[i]%2==1)color[i]=1;
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(!rec[A[i]+A[j]]){
graph[i].add(j);
graph[j].add(i);
}
}
}
int ret=0;
for(int i=0;i<n;i++){
if(color[i]==0&&dfs(i,new boolean[n])){
ret++;
}
}
out.println(ret);
}
private boolean dfs(int node, boolean[] vis) {
if(vis[node]){
return false;
}
vis[node]=true;
for(int nn:graph[node]){
if(match[nn]==-1||dfs(match[nn],vis)){
match[nn]=node;
return true;
}
}
return false;
}
//input
@SuppressWarnings("unused")
private ArrayList<Integer>[] ng(int n, int m) {
ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
for(int i=0;i<n;i++) {
graph[i]=new ArrayList<>();
}
for(int i=1;i<=m;i++) {
int s=in.nextInt()-1,e=in.nextInt()-1;
graph[s].add(e);
graph[e].add(s);
}
return graph;
}
private ArrayList<long[]>[] ngw(int n, int m) {
ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
for(int i=0;i<n;i++) {
graph[i]=new ArrayList<>();
}
for(int i=1;i<=m;i++) {
long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
graph[(int)s].add(new long[] {e,w});
graph[(int)e].add(new long[] {s,w});
}
return graph;
}
private int ni() {
return in.nextInt();
}
private long nl() {
return in.nextLong();
}
private double nd() {
return in.nextDouble();
}
private String ns() {
return in.next();
}
private long[] na(int n) {
long[] A=new long[n];
for(int i=0;i<n;i++) {
A[i]=in.nextLong();
}
return A;
}
private int[] nia(int n) {
int[] A=new int[n];
for(int i=0;i<n;i++) {
A[i]=in.nextInt();
}
return A;
}
}
class FastReader
{
BufferedReader br;
StringTokenizer st;
public FastReader()
{
br=new BufferedReader(new InputStreamReader(System.in));
}
public boolean hasNext(){
try{
String s=br.readLine();
if(s==null){
return false;
}
st=new StringTokenizer(s);
}catch(IOException e){
e.printStackTrace();
}
return true;
}
public String next()
{
while(st==null || !st.hasMoreElements())//回车,空行情况
{
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt()
{
return Integer.parseInt(next());
}
public long nextLong()
{
return Long.parseLong(next());
}
public double nextDouble()
{
return Double.parseDouble(next());
}
}