You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_10_4_week;
// 来自华为
// 若两个正整数的和为素数,则这两个正整数称之为"素数伴侣"
// 给定N(偶数)个正整数中挑选出若干对,组成"素数伴侣"
// 例如有4个正整数25613
// 如果将5和6分为一组的话只能得到一组"素数伴侣"
// 如果将2和5、6和13编组将得到两组"素数伴侣"
// 这是得到"素数伴侣"最多的划分方案
// 输入:
// 有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
// 输出:
// 输出一个整数 K ,表示最多能找出几对"素数伴侣"
// 数据范围: 1 <= n <= 100, 2 <= val <= 30000
// 测试链接 : https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.io.IOException;
public class Code01_MaxPrimePairs {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int) in.nval;
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
int[][] graph = matrix(arr, n);
out.println(km(graph) / 2);
out.flush();
}
}
public static int[][] matrix(int[] arr, int n) {
int[][] ans = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
ans[i][j] = isPrime(arr[i] + arr[j]) ? 1 : 0;
}
}
return ans;
}
public static boolean isPrime(int num) {
int sqrt = (int) Math.sqrt(num);
for (int i = 2; i <= sqrt; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static int km(int[][] graph) {
int N = graph.length;
int[] match = new int[N];
int[] lx = new int[N];
int[] ly = new int[N];
boolean[] x = new boolean[N];
boolean[] y = new boolean[N];
int[] slack = new int[N];
int invalid = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
match[i] = -1;
lx[i] = -invalid;
for (int j = 0; j < N; j++) {
lx[i] = Math.max(lx[i], graph[i][j]);
}
ly[i] = 0;
}
for (int from = 0; from < N; from++) {
for (int i = 0; i < N; i++) {
slack[i] = invalid;
}
Arrays.fill(x, false);
Arrays.fill(y, false);
while (!dfs(from, x, y, lx, ly, match, slack, graph)) {
int d = invalid;
for (int i = 0; i < N; i++) {
if (!y[i] && slack[i] < d) {
d = slack[i];
}
}
for (int i = 0; i < N; i++) {
if (x[i]) {
lx[i] = lx[i] - d;
}
if (y[i]) {
ly[i] = ly[i] + d;
}
}
Arrays.fill(x, false);
Arrays.fill(y, false);
}
}
int ans = 0;
for (int i = 0; i < N; i++) {
ans += (lx[i] + ly[i]);
}
return ans;
}
public static boolean dfs(int from, boolean[] x, boolean[] y, int[] lx, int[] ly, int[] match, int[] slack,
int[][] map) {
int N = map.length;
x[from] = true;
for (int to = 0; to < N; to++) {
if (!y[to]) {
int d = lx[from] + ly[to] - map[from][to];
if (d != 0) {
slack[to] = Math.min(slack[to], d);
} else {
y[to] = true;
if (match[to] == -1 || dfs(match[to], x, y, lx, ly, match, slack, map)) {
match[to] = from;
return true;
}
}
}
}
return false;
}
}