/**
- 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,
- 输出时从整数1开始,逆时针排列。同一个环应恰好输出一次。
- n<=16
- 如输入:6
- 输出:
- 1 4 3 2 5 6
- 1 6 5 2 3 4
*/
题解:递归+深搜+回溯思想 解题 ,相当于全排列,枚举所有的可能,再最后处理环的问题
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
List<List<Integer>> res=new ArrayList<>();
int[] a =new int[n+1]; //第0个位置废弃不用
for (int i = 1; i <=n; i++) {
a[i]=i; //填充数组
}
boolean[] used=new boolean[n+1]; //定义保存状态的数组
Deque<Integer> path=new ArrayDeque<>(); //创建栈用于保存临时的排列状态
path.addLast(1); //先将1加入到栈中
used[1]=true; //标记为已使用
dfs(a,path,1,used,res); //进行深搜,枚举可能的结果
for (List<Integer> re : res) { //排除不是素数环的结果
int sum=re.get(0)+re.get(n-1);
if(is_Su(sum))
System.out.println(re); //输出素数环
}
}
private static void dfs(int[]a,Deque<Integer> path,int depth , boolean[] used,List<List<Integer>> res) {
if (depth==a.length-1){
res.add(new ArrayList<>(path)); //当层数等于数组长度说明,枚举到一种可能
return;
}
for (int i = 2; i<a.length ; i++) {
if (used[i]==true)
continue;
int t_sum=a[i]+ path.getLast().intValue(); //将上一个素数和本次可能组成素数的结果求和
if (is_Su(t_sum)){ //判断素数
path.addLast(a[i]); //尝试加入
used[i]=true; //标识为使用状态
dfs(a,path,depth+1,used,res); //进行下一次尝试,
path.removeLast(); //回溯,状态重置
used[i]=false; //恢复状态
}
}
}
private static boolean is_Su(int n){ //判断素数
for (int i = 2; i <= n/2 ; i++) {
if (n%i==0)
return false;
}
return true;
}