素数环 搜索
题目描述
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, …, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Iutput
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
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
思路:
题意:一串数首尾相接,要求相邻两个数字之间和为奇数;
用深度搜索解题;
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#define N 50
using namespace std;
int visit[N];//标记整数是否被访问
int ring[N];//用来存放满足素数环的整数
int n;//素数环的大小
bool isprime(int k)//判断是否为素数,由于题目给定的范围很小,所以可以用这种直接的方法判断,不会超时
{
bool tag;
tag=true;
if(k==2)
return tag;
for(int j=2; j*j<=k; j++)
{
if(k%j==0)
{
tag=false;
break;
}
}
return tag;
}
void dfs(int l)
{
if(l==n&&isprime(ring[l]+ring[1]))//最后一次,跳出递归,输出素数环
{
for(int i=1;i<n;i++)
printf("%d ",ring[i]);
printf("%d\n",ring[n]);
return;
}
for(int j=2; j<=n; j++)//因为题目要求打印的素数环要按照字典序排列,所以从小到大遍历整数
if(!visit[j]&&isprime(ring[l]+j))//未被访问过,并且满足与上一次记录的整数之和为素数
{
visit[j]=1;//标记该整数已被访问
ring[l+1]=j;//更改记录整数,用作下一次素数环的判断
dfs(l+1);//递归实现,参数表示已经找到的满足素数环的整数的个数
visit[j]=0;//回溯,因为下一次可能要用到该整数。
}
}
int main()
{
int cased=1;
while(scanf("%d",&n)!=EOF)
{
memset(ring,0,sizeof(ring));//置0
memset(visit,0,sizeof(visit));//初始化为0
ring[1]=1;//第一个整数为1
printf("Case %d:\n",cased++);
if(n%2==0&&n>0)//剪枝,如果为奇数肯定没有素数环,只有偶数才可能有素数环
dfs(1);
printf("\n");
}
return 0;
}