素数环
时间限制: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
典型深搜 用dfs做
#include <iostream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
int a[40], s[40]; //s 标记数组, a存储数据
int n;
int ispr(int n){
int i;
for (i=2; i<=sqrt(n); i++)
{
if (n%i==0)
break;
}
if (i>sqrt(n))
return 1;
else
return 0;
}
void dfs(int num)
{
if (num>n) //当搜索到尾部时
{
//printf ("sddadasd\n");
if (ispr(a[1]+a[n])) //尾部和头部的和 也为 素数
{
for (int i=1; i<n ; i++)
{
printf ("%d ",a[i]);
}
printf ("%d\n",a[n]);
}
return;
}
for (int i=2; i<=n ;i++)
{
//printf("s[i]: %d, i: %d, num: %d, a[num-1]: %d\n",s[i],i,num,a[num-1]);
if (!s[i]&&ispr(a[num-1]+i)) //当没有访问过并且 前一个和要加的和 是 素数
{
s[i] = 1; //访问过标记为1
a[num] = i;
dfs(num+1);
s[i]=0; //当返回时 重新标记为未访问状态
// printf("!!!!!i: %d , num: %d\n",i,num);
}
}
}
int main()
{
int count1=0;
while (scanf("%d",&n)!=EOF,n)
{
printf ("Case %d:\n",++count1);
memset(s, 0, sizeof(s));
s[1]=1; //每个素数环都含有1 所以1 默认为访问过
a[1]=1;
if (n==1)
{
printf ("1\n");
continue;
}
else if (n%2) //当为奇数时 无法构成
{
printf("No Answer\n");
continue;
}
else if (n>=2)
{
dfs(2);
}
}
return 0;
}