标题：素数环
定义
问题描述：将从1到n这n个整数围成一个圆环，若其中任意2个相邻的数字相加，结果均为素数，那么这个环就成为素数环。
n=20时，下面的序列就是一个素数环：
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18
英文名：Prime Ring Problem
代码
递归实现（C语言）#include <stdio.h>
#include <math.h>
#define LEN 20
int primeRing(int ring[], int b[], int n);
int isPrime(int n);
int main(void)
{
int i, ring[LEN]={0}, b[LEN]={0};
ring[0] = 1;
b[0] = 1;
if( primeRing(ring, b, 1) )
{
printf("\n\nThe prime ring is : ");
for(i=0; i<LEN; i++)
printf("%d ", ring[i]);
printf("\n");
}
else
printf("\n\nNot found!\n");
return 0;
}
int primeRing(int ring[], int b[], int n)
{
int i;
if( n==LEN )
return isPrime(ring[n-1]+ring[0]);
printf("\nCalculating ring[%d] = ", n);
for(i=1; i<LEN; i++)
if( b[i]==0 && isPrime((i+1)+ring[n-1]) )
{
b[i] = 1;
ring[n] = i+1;
printf("%d ", ring[n]);
if( primeRing(ring, b, n+1) )
return 1;
else
b[i] = 0;
}
return 0;
}
int isPrime(int n)
{
int i, t, f=1;
t = sqrt(n);
for(i=2; i<=t; i++)
if( n%i==0 )
{
f = 0;
break;
}
return f;
}
递归实现（C++）#include<iostream>
2 using namespace std;
3 int step[21];
4 int flag[21];
5 int a[42];
6 int n;
7 bool check(int x,int y)
8 {
9 if(a[x+y]&&!flag[y])
10 return true;
11 else
12 return false;
13 }
14 void dfs(int dp)
15 {
16 int i;
17 if(dp==n)
18 {
19 if(a[1+step[n-1]])
20 {
21 printf("1");
22 for(i=1;i<n;i++)
23 printf(" %d",step[i]);
24 printf("\n");
25 }
26 return;
27 }
28 for(i=2;i<=n;i++)
29 {
30 if(check(step[dp-1],i))
31 {
32 step[dp]=i;
33 flag[i]=1;
34 dfs(dp+1);
35 flag[i]=0;
36 }
37 }
38 }
39 int main()
40 {
41 int count=1;
42 memset(a,0,sizeof(a));
43 a[2]=a[3]=a[5]=a[7]=a[11]=a[13]=a[17]=1;
44 a[19]=a[23]=a[29]=a[31]=a[37]=a[41]=1;
45 while(~scanf("%d",&n))
46 {
47 printf("Case %d:\n",count++);
48 memset(flag,0,sizeof(flag));
49 step[0]=1;
50 flag[1]=1;
51 dfs(1);
52 printf("\n");
53 }
54 return 0;
55 }
递归实现（Pascal）const max=20;
type sz=array[1..max] of integer;
var z:integer;
a:sz;
res:text;
Procedure print;
var i:integer;
BEGIN
for i:=1 to max do write(a[i]:5); writeln;
END;
function su(x:integer):boolean;
var t:integer;
begin
su:=true;
for t:=2 to trunc(sqrt(x)) do
if x mod t=0 then su:=false;
end;
function buchongfu(n,x:integer):boolean;
var t:integer;
begin
buchongfu:=true;
for t:=1 to n do
if a[t]=x then
begin
buchongfu:=false;
break;
end;
end;
procedure find(z:longint);
var t:integer;
begin
if z<=max-1 then
begin
for t:=1 to max do
if su(t+a[z]) then
begin
if buchongfu(z,t) then
begin
a[z+1]:=t;
find(z+1);
end;
end;
end
else
if su(a[max]+1) then print;
end;
begin
assign(res,'result.txt');
rewrite(res);
a[1]:=1;
find(1);
close(res);
readln('Check result.txt');
end.
非递归实现（Java）public class Main {
public static void main(String[] args) {
primering(20);
}
public static void primering(int n) {
if(n % 2 != 0) {
System.out.println("若要实现素数环，元素的个数必须为偶数，您的输入不符合要求！");
return;
}
int[] a = new int[n];
a[0] = 1;
int i = 1;
boolean flag = true; // true表示正常向下一级移动，false表示回溯到上一级
int first;
while (i < n) {
//选择一个元素
//如果是正常向下一级移动，该元素应该是当前未使用的最小的数
//若是从下一层回溯上来的，则该元素为“比当前值大的，并且未被使用的，最小的一个数”
for1: for (a[i] = flag ? 2 : a[i] + 1; a[i] <= n; a[i]++) {
for (int j = 0; j < i; j++) {//检验选择的元素是否曾经用过
if (a[i] == a[j])
continue for1;
}
break;
}
//若选择的元素超过了最大值，则应该回溯
if (a[i] > n) {
i--;
flag = false;
continue;
}
// 如果当前找到的元素与前一个元素的和是素数
if (isPrime(a[i] + a[i - 1])) {
if (i < n - 1) { // 如果不是最后一个元素，则向下一级寻找
i++;
flag = true;
} else if (isPrime(a[i] + a[0])) { // 如果是最后一个元素并且于环的第一个元素的和仍然是素数
break; //则素数环已经找到，退出循环
} else { //若是最后一个元素，并且不满足素数环
i--; //则向上一级回溯
flag = false;
}
} else { //若当前元素不满足素数环，则继续寻找
flag = false;
}
}
//打印素数环
for(int x:a) {
System.out.print(x+" ");
}
}
public static boolean isPrime(int n) {
int i;
for (i = 2; i < n; i++)
if (n % i == 0)
break;
return i==n;
}
}
运行结果：
C:\test>java Main
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18