/*素数环
* 问题描述:输入正整数n,把整数1,2,3,...,n组成一个环,使得相邻两个整数之和均为素数。
* 输出时从整数1开始逆时针排列。同一个环应恰好输出一次.n<=16
* 思路:使用回溯法,每次递归或者确定一个位置上的数或者找不到合法的就退出至上层递归
* 辅助变量vis记录本次递归时整数是否已经被使用,注意退出递归时恢复原始状态
* */
import java.util.Arrays;
import java.util.Scanner;
public class PrimeCircle {
static final int MAXN = 17;
static int vis[] = new int[MAXN];
static int[] a = new int[MAXN];
static boolean[] isp = new boolean[MAXN * 2 + 1];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n;
fillIsp();
while ((n = scanner.nextInt()) > 0 && n <= 16) {
Arrays.fill(vis, 0);
a[0] = 1;
vis[0] = 1;
dfs(1, n);
}
}
private static boolean isPrime(int n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0)
return false;
}
return true;
}
private static void fillIsp() {
isp[1] = false;
isp[2] = true;
for (int i = 3; i <= MAXN * 2; i++)
isp[i] = isPrime(i);
}
private static void dfs(int cur, int n) {
if (cur == n && isp[a[n - 1] + a[0]]) {// 递归边界
for (int i = 0; i < n; i++)
System.out.printf("%d ", a[i]);
System.out.println();
} else
for (int i = 2; i <= n; i++) {
if (vis[i] == 0 && isp[i + a[cur - 1]]) {// 如果i没有被用过
a[cur] = i;
vis[i] = 1;
dfs(cur + 1, n);
vis[i] = 0;
}
}
}
}
素数环
最新推荐文章于 2024-03-11 23:03:34 发布