有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。
为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。
6 8 3 0
Case 1: 1 4 3 2 5 6 1 6 5 2 3 4 Case 2: 1 2 3 8 5 6 7 4 1 2 5 8 3 4 7 6 1 4 7 6 5 8 3 2 1 6 7 4 3 8 5 2 Case 3: No Answer
题目中要求以从1开始,所以以1为起点。本题有一个规律,就是当数为1或者是偶数是才有素数环,除了1以外,奇数都没有素数环,这一点对题目要求的没有素数环时输出No Answer 条件的实现很重要,因为如果不用这个规律,而在程序中实现,比较困难(我没有想到)。
代码如下:
<span style="font-size:18px;"><strong>#include<stdio.h> #include<math.h> #include<string.h> int a[25],b[25];//b数组是标记数组,用于标记下标所代表的数是否被用过 int n; int su(int n)//判断素数 { int i; for( i=2;i<=sqrt(n);i++) { if(n%i==0) break; } if(i<=sqrt(n)) return 0; else return 1; } int dfs(int s) { if(s==n&&su(a[0]+a[n-1]))//当s==n时,也就是a数组以0到n-1为下标的空间已经有数,或者说现在是一条长链,</strong></span><span style="font-size:18px;"><strong> //如果第一个和最后一个数的和是素数,就可以组成一个素数环,循环输出a数组即可。</strong></span>
<strong><span style="font-size:18px;"> { for(int j=0;j<n;j++) { printf("%d ",a[j]); } printf("\n"); return 1; } for(int k=2;k<=n;k++) { if(b[k]==0&&su(k+a[s-1]))//找一个没有被用过的数,并且此数和上一个数的和是素数 { a[s]=k;//把这个数存入,也就是把此数加入素数环 b[k]=1;//标记此数已经被用过 dfs(s+1);//本阶段已经做完,寻找下一个数 b[k]=0;//释放标记,不干扰下一次 } } } int main(void) { int count;//作为题目要求的Case 的计数器 count=1; while(scanf("%d",&n)!=EOF) { if(n==0)//要求以0作为程序的结束 return 0; memset(a,0,sizeof(a));//其实此数组不置为0也可以,因为会直接覆盖 memset(b,0,sizeof(b));//此数组要置为0 a[0]=1;//素数环的起点是1 printf("Case %d:\n",count); if(n%2==0||n==1)//运用上面提到的规律 { dfs(1);//从1开始 } else if(n%2!=0) printf("No Answer\n"); count=count+1; }</span><span style="font-size: 14px;"> return 0; }</span></strong>
原文地址:http://blog.csdn.net/u013240038/article/details/45130563