问题描述:
输入正整数n ,把整数1, 2, 3… n组成一个环,使得相邻两个整数之和均为素数。输出.时从整数l开始逆时针排列。同一个环应恰好输出一次。n<16。
样例输入:
6
样例输出:
1 43256
1 65234
思路分析:
第一次看这个题目,最直接的方法就是对数组进行全排列,然后遍历所有情况,看哪些情况符合,筛选出来即可。如果使用dfs方法的话,就是要在数组的位置上进行试探性放入值,如果这个值和数组的前一个值的和是素数(特别注意如果是最后一个数,不仅要和其前一个数字进行相加判断,也要和第一个数字进行相加判断),直到到达数组的尽头(也就是递归的出口)。
注意:每次判断是否为质数和的时候,也要判断新加入的数字是否和前面的数字发生重复,如果重复,return false;(也要注意位置n对于判断条件的分割)。
具体看代码注释:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Shh {
//素数环(dfs)
public static void Shhs(int []a, int n, ArrayList<String> b)//利用n表示状态转移,利用list记录结果
{
if (n==a.length)//递归出口
{
StringBuilder s=new StringBuilder();
for (int i:a) {
s.append(i);
}
b.add(s.toString());//将结果加入到list中
return;
}
for (int i=1;i<=a.length;i++)
{
if (check(a,n,i))
{
a[n]=i;//修改当前状态
Shhs(a,n+1,b);//状态转移
a[n]=0;//回溯
}
}
}
public static boolean checksushu(int a)//判断是否为素数
{
for (int i=2;i<=Math.sqrt(a);i++)
{
if (a%i==0)
return false;
}
return true;
}
public static boolean check(int []a,int b,int c)//判断在数组n处放入c是否可行
{
if (b==0)
{
return true;
}
else if (b<a.length-1)
{
for (int i=0;i<b;i++)//判断前面是否出现相同的数字
{
if (c==a[i])
return false;
}
if (checksushu(a[b-1]+c))//判断和是否为质数
{
return true;
}
}
else
{
for (int i=0;i<b;i++)//判断前面是否出现相同的数字
{
if (c==a[i])
return false;
}
if (checksushu(a[b-1]+c)&&checksushu(a[0]+c))//判断和是否为质数
return true;
}
return false;
}
public static void main(String[] args) {
Scanner a=new Scanner(System.in);//输入个数
int b=a.nextInt();
int []c=new int[b];
Arrays.fill(c,0);//数组填充
ArrayList<String> ss=new ArrayList<>();//记录原始字符串
Shhs(c,0,ss);
ArrayList<String> news=new ArrayList<>();//用于记录帅选出来的字符串
for (String i:ss) {
if (i.charAt(0)=='1')
news.add(i);
}
if (news.size()==0)
System.out.println("没有相应的素数环");
else
System.out.println(news);//结果输出
}
}
相应的运行结果如下: