**问题:**把整数{1,2,…20}填写到一个环中,要求每个整数只填写一次,并且相邻的两个整数之和是一个素数。
约束条件如下:
(1)与已经填写到素数环中的整数不重复
(2)与前面相邻的整数之和是一个素数
(3)最后一个填写到素数环中的整数与第一个填写的整数之和是一个素数
在填写第k个位置时,如果满足上述条件,则继续填写第k+1个位置;如果1-20都无法填写到第k个位置,则取消第k个位置的填写,回溯到第k-1个位置。
*JAVA代码如下所示:(对其代码行做了注释)
package practical;
import java.util.Scanner;
public class Primecircle {
public static void PrimeCircle(int n,int[] a) {//填写1-n共n个数
int i,k;
for(i=0;i<n;i++)//将数组a[n]初始化为0
a[i]=0;
a[0]=1;k=1;//指定第0个位置填写1
while(k>=1) {
a[k]=a[k]+1;
while(a[k]<=n)
if(Check(k,a)==1) break;//位置k可以填写整数a[k]
else a[k]=a[k]+1;//试探下一个数
if(a[k]<=n&&k==n-1)//求解完毕输出解
{
System.out.println("输出对应的素数环:");
for(i=0;i<n;i++)
System.out.printf(a[i]+" ");//a[i]后接空格是为了输出的时候留有间隙易于区分
return;
}
if(a[k]<=n&&k<n-1)
k=k+1;//填写下一个位置
else
a[k--]=0;
}
}
public static int Check(int k,int[] a) {//判断位置k的填写是否满足约束条件
int flag=0;
int n = a.length;
for(int i=0;i<k;i++)//判断是否重复
if(a[i]==a[k]) return 0;
flag=Prime(a[k]+a[k-1]);//判断相邻数之和是否为素数
if(flag==1&&k==n-1)//判断第一个和最后一个是否为素数
flag=Prime(a[k]+a[0]);
return flag;
}
public static int Prime(int x) {//判断整数是否为素数
int i,n;
n=(int)Math.sqrt(x);
for(i=2;i<=n;i++)
if(x%i==0) return 0;
return 1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("输入整数n的值为:");
int n=sc.nextInt();
int[] a=new int[n];
long startTime = System.currentTimeMillis(); //获取开始时间
PrimeCircle(n,a);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("");
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
sc.close();
}
}
运行结果截图:
输入n的值是素数环中指定的个数,可以自己输入指定的n值,这样不至于将其规定死,想要求多少个整数的素数环都是可以的。
对于代码主函数部分加上了对于代码段运行时间进行了统计,统计代码段运行时间的基本格式如下所示:
long startTime = System.currentTimeMillis(); //获取开始时间
PrimeCircle(n,a);(所要测试的代码区自己指定)我这里是测试输入不同
n值测试其运行时间
long endTime = System.currentTimeMillis(); //获取结束时间
为本人日常学习分享,有问题希望大佬们指正,彼此多多交流学习。