素数环
时间限制:
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<stdio.h> #include<math.h> #define max 21 int visit[max],a[max]; int n; int prime(int x)//用于判断两数之和是不是素数 { int i; if(x==3&&x==2) return 1; if(x==1) return 0; for(i=2;i<=sqrt(x);i++) { if(x%i==0) return 0; } return 1; } void dfs(int num,int n)//用num表示进行搜索的次数 { int i,j; if(num==n+1&&prime(a[n]+1))//num=n+1说明n个数已搜索完,但还需首尾之和为素数 { for(i=1;i<=n;i++) { if(i>1) printf(" "); printf("%d",a[i]); } printf("\n"); return ; } else { for(i=2;i<=n;i++) { if(visit[i]==0&&prime(a[num-1]+i)) { visit[i]=1; a[num]=i; dfs(num+1,n); visit[i]=0; } } return ; } } int main() { int i,j=1; while(scanf("%d",&n)&&(n!=0)) { for(i=1;i<=n;i++) { a[i]=0; visit[i]=0;//初始化 } a[1]=1;visit[1]=1; printf("Case %d:\n",j++); if(n&1) { if(n==1) printf("1\n"); else printf("No Answer\n"); } else { dfs(2,n); } } return 0; }
-
#include<stdio.h> #include<string.h> #define max 50+10 int a[max],prime[max],visit[max]; int n,t=1; void Prime() { int i,j; for(i=2;i<max;i++) { if(prime[i]==1) { for(j=2*i;j<max;j+=i) { prime[j]=0; } } } prime[1]=0;prime[2]=prime[3]=1; } void dfs(int num,int n) { int i,j; if(num==n+1&&prime[a[n]+1]) { for(i=1;i<=n;i++) { if(i>1) printf(" "); printf("%d",a[i]); } printf("\n"); return ; } else { for(i=2;i<=n;i++) { if(!visit[i]&&prime[a[num-1]+i]) { visit[i]=1; a[num]=i; dfs(num+1,n); visit[i]=0; } } return ; } } int main() { int i,j; for(i=1;i<max;i++) prime[i]=1; Prime(); while(scanf("%d",&n)&&(n!=0)) { printf("Case %d:\n",t++); for(i=1;i<=n;i++) { visit[i]=0; a[i]=0; } a[1]=1;visit[1]=1; if(n&1) { if(n==1) printf("1\n"); else printf("No Answer\n"); } else { dfs(2,n); } } return 0; }