素数环
时间限制:
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<string.h>
#include<math.h>
int n = 0;
int a[20];
int b[20];
int count = 1;
int isprime(int m)
{
int len, i;
if(m < 3)
return 0;
len = (int)sqrt(m + 0.0);
for(i = 2; i <= len; i++)
{
if(m % i == 0)
return 0;
}
return 1;
}
void back(int cur)
{
int i, flag = 0;
// p = count;
if(cur == n && isprime(a[0] + a[n - 1])) //递归结束的条件
{
// printf("Case %d:\n", count++);
for(int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");//flag = 1;
return;
}
// if(!flag && cur == n){printf("Case %d:\n", count++);printf("No Answer\n");}
else
for(i = 2; i <= n; i++)
{
if(!b[i] && isprime(i + a[cur - 1]))
{
a[cur] = i;
b[i] = 1;
back(cur + 1);
b[i] = 0; //回溯时重新标记已经用过的数字为0
}
}
}
int main()
{
int i;
for(i = 0; i< 20; i++)
a[i] = i + 1;
memset(b, 0, sizeof(b));
while(scanf("%d", &n) && n)
{
if(n == 1)
{
printf("Case %d:\n", count++);
printf("1\n");
}
else
{
if(n %2 ) //当n为奇数时不可能形成素数环 (两个奇数相加一定为偶数)
{
printf("Case %d:\n", count++);
printf("No Answer\n");
continue;
}
printf("Case %d:\n", count++);
back(1); //回溯时第一个数字为1
}
}
}