23025: 素数环
题目描述
一个大小为N(N<=17)的质数环是由1到N共N个自然数组成的一个数环,数环上每两个相邻的数字之和为质数。如下图是一个大小为6的质数环。为了方便描述,规定数环上的第一个数字总是1。如下图可用1 4 3 2 5 6来描述。若两个质数环,数字排列顺序相同则视为本质相同。现在要求你求出所有本质不同的数环。
输入
输入1行:一个正整数N,表示质数环的大小。
输出
输出多行:每一行描述一个数环,如果有多组解,按照字典序从小到大输出,如果无解则不输出。
样例输入
6
样例输出
1 4 3 2 5 6
1 6 5 2 3 4
题目链接:http://arena.acmclub.com/problem.php?id=23025
简单运用一下回溯的模板。。
import java.util.Scanner;
public class Main23025 {
static int n;
static int[] a = new int[50];
static boolean[] vis = new boolean[50];
static boolean[] isp = new boolean[50];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
n = in.nextInt();
a[0] = 1;
for (int i = 2; i <= n * 2; i++)
isp[i] = isPrime(i);
dfs(1);
}
}
public static void dfs(int cur) {
if (cur == n && isp[a[n - 1] + a[0]]) { //递归边界
for (int i = 0; i < n; i++) { //打印方案
if (i == n - 1)
System.out.println(a[i]);
else
System.out.print(a[i] + " ");
}
} else {
for (int i = 2; i <= n; i++) { //尝试放置每个i,第一个位置为1(保证最小),故从2开始
if (!vis[i] && isp[i + a[cur - 1]]) { //如果i没用过,并且与前一个数之和为素数
a[cur] = i;
vis[i] = true; //设置标记
dfs(cur + 1);
vis[i] = false; //清除标记
}
}
}
}
public static boolean isPrime(int n) {
if (n < 2)
return false;
for (int j = 2; j * j <= n; j++)
if (n % j == 0)
return false;
return true;
}
}