一、问题描述
把整数1~n填写到一个环中,要求每个整数只能填写一次,并且相邻两个数的和为素数。
素数是只能被1和自身整除的整数。
二、问题分析
详见注释
三、算法代码
public static void primeCircle(int [] place){
int n = place.length;
for(int i = 0; i <= place.length - 1; i++){
place[i] = 0;
}
int k = 1;
place[0] = 1; //指定第0个位置放置1
while(k >= 1){
place[k]++;
while(place[k] <= n){//判定位置k能否放置数值place[k]
if(check(k, place)){
break; //位置k可以放置place[k]
}else{
place[k]++; //尝试放置下一个数
}
}
if(place[k] <= n && k == n - 1){//找到一种放置方法
for(int i = 0; i < n; i++){
System.out.println(place[i]);
}
return;
}
if(place[k] <= n && k < n){//开始放置下一个位置
k++;
}else{//前0~k-1个位置的放置方式导致当前位置k无法放置符合要求的数,开始回溯。
place[k] = 0;
k--;
}
}
}
public static boolean check(int k, int [] place){//检查当前位置能否放置place[k]
int n = place.length;
for(int i = 0; i < k; i++){
if(place[i] == place[k]){//数字放置重复
return false;
}
}
boolean primeFlag = prime(place[k - 1] + place[k]);//判断前后两数之和是否为素数
if(primeFlag == true && k == n -1){//判断环的第一个数和最后一个数的和是否为素数
primeFlag = prime(place[0] + place[k]);
}
return primeFlag;
}
public static boolean prime(int num){//判断num是否为素数
int root = (int) Math.sqrt(num);
for(int i = 2; i <= root; i++){
if(num % i == 0){
return false;
}
}
return true;
}
四、完整测试代码
public class Solution {
public static void main(String [] args){
int n = 10;
int [] place = new int[n];
primeCircle(place);
}
public static void primeCircle(int [] place){
int n = place.length;
for(int i = 0; i <= place.length - 1; i++){
place[i] = 0;
}
int k = 1;
place[0] = 1; //指定第0个位置放置1
while(k >= 1){
place[k]++;
while(place[k] <= n){//判定位置k能否放置数值place[k]
if(check(k, place)){
break; //位置k可以放置place[k]
}else{
place[k]++; //尝试放置下一个数
}
}
if(place[k] <= n && k == n - 1){//找到一种放置方法
for(int i = 0; i < n; i++){
System.out.println(place[i]);
}
return;
}
if(place[k] <= n && k < n){//开始放置下一个位置
k++;
}else{//前0~k-1个位置的放置方式导致当前位置k无法放置符合要求的数,开始回溯。
place[k] = 0;
k--;
}
}
}
public static boolean check(int k, int [] place){//检查当前位置能否放置place[k]
int n = place.length;
for(int i = 0; i < k; i++){
if(place[i] == place[k]){//数字放置重复
return false;
}
}
boolean primeFlag = prime(place[k - 1] + place[k]);//判断前后两数之和是否为素数
if(primeFlag == true && k == n -1){//判断环的第一个数和最后一个数的和是否为素数
primeFlag = prime(place[0] + place[k]);
}
return primeFlag;
}
public static boolean prime(int num){//判断num是否为素数
int root = (int) Math.sqrt(num);
for(int i = 2; i <= root; i++){
if(num % i == 0){
return false;
}
}
return true;
}
}
五、运行结果
1
2
3
4
7
6
5
8
9
10