华为机测题:素数伴侣
题目描述
- 题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如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个整数
注意:数据可能有多组
输出描述:
- 求得的“最佳方案”组成“素数伴侣”的对数。
链接:【匈牙利算法】简单易懂
链接:【素数判断的几个方法】简单理解
代码:
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String readIn;
while((readIn=br.readLine())!=null){
int n = Integer.parseInt(readIn);
String[] str_nums = br.readLine().split(" ");
ArrayList<Integer> nums = new ArrayList<Integer>();
int odd_count=0;
for(String s:str_nums){
int i = Integer.valueOf(s);
nums.add(i);
if(i%2==1) odd_count++;
}
int[] odd_nums=new int[odd_count],even_nums=new int[n-odd_count];
int even_idx=0,odd_idx=0;
for(int i:nums){
if(i%2==0){
even_nums[even_idx++]=i;
}else{
odd_nums[odd_idx++]=i;
}
}
int[] num=new int[n-odd_count];
boolean[] used;
int ans=0;
for(int i=0;i<odd_count;i++){
used = new boolean[n-odd_count];
if(find(odd_nums[i],even_nums,num,used)){
ans++;
}
}
System.out.println(ans);
}
}
public static boolean find(int n,int[] evens,int[] num,boolean[] used){
for(int i=0;i<evens.length;i++){
if(isP(n+evens[i])&&!used[i]){
used[i]=true;
if(num[i]==0||find(num[i],evens,num,used)){
num[i]=n;
return true;
}
}
}
return false;
}
public static boolean isP(int num) {
if (num <= 3) {
return num > 1;
}
if (num % 6 != 1 && num % 6 != 5) {
return false;
}
int sqrt = (int) Math.sqrt(num);
for (int i = 5; i <= sqrt; i += 6) {
if (num % i == 0 || num % (i + 2) == 0) {
return false;
}
}
return true;
}
}