素数环
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描述
-
有一个整数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<stdio.h>
#include<math.h>
int a[21],n,flag;//flag变量用来标记是否找到过素数环
int swap(int n,int i)//交换a[i]和a[n]用的,不是交换i和n。
{
int t;
t=a[i];
a[i]=a[n];
a[n]=t;
}
void print(int a[])//用于输出找到的素数环
{
int i;
for(i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
}
int is_prime(int k)//判断一个数是不是素数用
{
int i,j;
j=(int)sqrt(k);
for(i=2;i<=j;i++)
if(k%i==0) return 0;
return 1;
}
void search(int m)//递归搜素
{
int i;
if(m>n)//已经搜索到了边界
{
if(is_prime(a[n]+a[1])) //当已经搜索到叶结点时,表示最后一个和他前面的也判断过了,再判断如果第一个和最后一个首位相接也是素数,则输出。
{
print(a);
flag=1;
}
else return;
}
else
{
for(i=m;i<=n;i++)
{
swap(i,m);//判断a[m-1]+a[m]是否是素数
if(is_prime(a[m-1]+a[m])) search(m+1);//递归搜索下一个位置
swap(i,m);//重新把a[m]和a[i]换回来
}
}
}
int main()
{
int k=1,i;
while(scanf("%d",&n),n)
{
flag=0;
for(i=1;i<=n;i++)
a[i]=i;
printf("Case :%d\n",k++);
search(2);
if(flag==0) printf("No answer\n");
}
return 0;
}