描述
有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。
为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。
-
输入
- 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。 输出
-
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
-
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
#include<iostream>
#include<ctype.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
int ans[20],b[20],p[40];
int n;
int judge_prime(int x)
{
if(x==0||x==1)
return 0;
for(int j=2;j<=sqrt(x);j++)
if(x%j==0)
return 0;
return 1;
}
void fun(int k)
{
int i;
if(k==n+1)//搜索到了足够的元素
{
if(!p[ans[n]+ans[1]])//如果头加尾不是素数 那也不行。
return;
for(i=1;i<=n-1;i++)//快乐的输出结果
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
return;
}
for(i=2;i<=n;i++)//遍历可用的数字
{
if(!b[i]&&p[ans[k-1]+i])
{
b[i]=1; //把该数字标记成1 表示已经用过。
ans[k]=i;
fun(k+1);
b[i]=0;//核心。fun函数回来了,说明该数字没用上,标记恢复0,
}
}
}
int main()
{
for(int i=1;i<40;i++)
{
if(judge_prime(i))
p[i]=1;//代表该数为素数。
else
p[i]=0;
}
int t=1;
while(scanf("%d",&n)!=EOF&&n!=0)
{
printf("Case %d:\n",t++);
if(n==1)//特殊情况
printf("1\n");
else if(n%2)
printf("No Answer\n");
else
{
ans[1]=1;
memset(b,0,sizeof(b));
fun(2);//从数组的第二个数字开始判断
}
}
return 0;
}