/*
NYOJ-488 素数环
素数环
时间限制: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
*/
/*
素数环:给定n,1~n组成一个素数环,相邻两个数的和为素数。
首先偶数(2例外,但是本题不会出现两个数的和为2)不是素数,
所以素数环里奇偶间隔。如果n是奇数,必定有两个奇数相邻的情况。
所以当n为奇数时,输出“No Answer”。
当n == 1时只1个数,算作自环,输出1
所有n为偶数的情况都能变成奇偶间隔的环-----所以都有结果。
*/
#include <stdio.h>
int count=1;
int a[21],c[21];//数组a为数字存储的数组 c数组存储要输出的数字组合
int b[21]={0};//数组b作为对应的数组a的值是否有被访问过的标记
int n,ds=1,x=0;//ds为判断两数之和是否为素数的前一个已经排好的数 x表示是第几种情况
void fun(int d[])
{
for(int i=0;i<n;i++)
{
printf("%d ",c[i]);
}
printf("\n");
}
int judge(int k)//判断两数之和是否为素数的函数
{
int e;
for(int i=2;i<=k;i++)
{
if(k%i==0)
{
e=i;
break;
}
}
if(e==k)
{
return 1;
}
else
{
return 0;
}
}
void f(int m,int sum)//递归函数
{
if(sum==n)
{
if(judge(c[sum-1]+1))
fun(c);
return ;
}
for(int i=2;i<=m;i++)
{
if(b[i]==0)
{
if(judge(ds+a[i]))
{
c[sum]=a[i];
b[i]=1;
ds=a[i];
f(m,sum+1);
ds=c[sum-1];//去除标记 这行代表ds存储的是当前选择过的数字的前一个已选定的数字
b[i]=0;//去除标记 表示对应的a[i]数字未被访问过
}
}
}
}
int main()
{
scanf("%d",&n);
while(n!=0)
{
x=x+1;
for(int j=1;j<=n;j++)
{
a[j]=j;
}
c[0]=1;//总是从1 开始
printf("Case %d:\n",x);
/*if(n==1)
{
printf("1\n");//单数字一个1 也算作一个环 一个回到它自身的环
}*/
if(n%2!=0&&n>1)//此时n为大于1的奇数 然而奇数组成的环中总会有两个奇数是相邻的
{//然而他们的和为偶数 不会是素数 所以排除
printf("No Answer\n");
}
else
{
f(n,1);
}
scanf("%d",&n);
}
return 0;
}
nyoj488 素数环
最新推荐文章于 2019-03-14 17:12:29 发布