DFS搜索,实现做预处理可以加快速度。
1. 由于0<n<20,可以先算出3~19+18的所有数是不是质数。
2. 可以事先算出每个数可以与哪些数组合,直接使用减少for循环次数
JAVA版当输出数据量大时不要使用System.out,使用PrintWriter。
以前用System.out一直4000MS TLE,用PrintWriter是600MS
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main {
int N;
boolean[] appeard = new boolean[20];
int[] path = new int[20];
boolean[] isprime = new boolean[38];
int[][] table = new int[20][20];
PrintWriter out;
public boolean isPrime(int num) {
int sqrt = (int) Math.floor(Math.sqrt(num));
for (int i = 2; i <= sqrt; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) throws IOException {
new Main().work();
}
public void work() throws IOException {
Scanner input = new Scanner(System.in);
out = new PrintWriter(new OutputStreamWriter(System.out));
for (int i = 3; i < isprime.length; i++) {
isprime[i] = isPrime(i);
}
int index;
for (int i = 1; i < 20; i++) {
index = 0;
for (int j = 1; j < 20; j++) {
if (i == j) {
continue;
}
if (isprime[i + j]) {
table[i][index++] = j;
}
}
}
appeard[1] = true;
path[1] = 1;
int counter = 1;
while (input.hasNext()) {
N = input.nextInt();
input.nextLine();
out.println("Case " + counter++ + ":");
dfs1(1);
out.println();
out.flush();
}
input.close();
}
public void dfs1(int alreadyAppeardCount) throws IOException {
int previous = path[alreadyAppeardCount];
int next;
if (alreadyAppeardCount == N) {
if (isprime[previous + 1]) {//*//
for (int i = 1; i <= N; i++) {
out.print(path[i]);
if (i != N) {
out.print(" ");
} else {
out.println();
}
}
}
}
for (int i = 0; i <= N; i++) {
next = table[previous][i];
if (next == 0) {
return;
}
if (next > N) {
continue;
}
if (appeard[next]) {
continue;
}
appeard[next] = true;//*//
path[alreadyAppeardCount + 1] = next;
dfs1(alreadyAppeardCount + 1);//*//
appeard[next] = false;//*//
}
}
}