Time Limit:1000MSMemory Limit:30000KB
Total Submit:413Accepted:243
Description
一个由自然数 1..n (n < 20)素数环就是如下图所示,环上任意两个节点上数值之和为素数。
1
/
4 2
/
3
Input
输入只有一个数n,表示你需要建立一个1..n的素数环。
Output
按照字典序输出每一种情况。我们约定顺时针为正向,且第一个元素必须是1,参见Sample。
Sample Input
6
Sample Output
1 4 3 2 5 6
1 6 5 2 3 4
Source
题目:EOJ1114
题目分析:1,若n为奇数,在一个环中必然存在相邻两数同为奇数,其和为偶数补位质数,故n比为偶数。
2,可将20内的质数存在一个hash表中,则可在O(1)内判断两数和是否为质数。
3.用dfs按层次遍历,按字典序输出,故从第一层开始从1到n尝试,若这个数符合要求(之前未被使用,与前一数之和为质数),则将此数存在遍历路径中,并往下一层遍历;否则回溯,将该数置为未被访问,路径长度减一。当dfs到最后一层,若第n个数和第1个数之和质数,则成功,依次输出遍历路径。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[22]={0,1,0};
int p[12]={1,2,3,5,7,11,13,17,19,23,29,31};
bool used[21];
bool is_prime(int k){
for(int i=0;i<12;++i)
if(p[i]==k)
return true;
return false;
}
void dfs(int deep,int n){
if(deep>n){
if(is_prime(a[n]+1)){
for(inti=1;i<=n;++i){
if(i>1)printf(" ");
printf("%d",a[i]);
}
printf("\n");
return ;
}
}
int i;
for(i=2;i<=n;++i){
if(!used[i] &&is_prime(i+a[deep-1])){
a[deep]=i;
used[i]=true;
dfs(deep+1,n);
used[i]=false;
}
}
}
int main()
{
int n;
cin>>n;
memset(used,false,sizeof(used));
if(!(n&1)){
dfs(2,n);
}
return 0;
}