nyoj素数环(dfs)

来源:互联网 发布:网络数据库和搜索引擎 编辑:程序博客网 时间:2024/05/16 14:46

素数环

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
6830
样例输出
Case 1:1 4 3 2 5 61 6 5 2 3 4Case 2:1 2 3 8 5 6 7 41 2 5 8 3 4 7 61 4 7 6 5 8 3 21 6 7 4 3 8 5 2Case 3:No Answer
题目中要求以从1开始,所以以1为起点。本题有一个规律,就是当数为1或者是偶数是才有素数环,除了1以外,奇数都没有素数环,这一点对题目要求的没有素数环时输出No Answer 条件的实现很重要,因为如果不用这个规律,而在程序中实现,比较困难(我没有想到)。
代码如下:
<span style="font-size:18px;"><strong>#include<stdio.h>#include<math.h>#include<string.h>int a[25],b[25];//b数组是标记数组,用于标记下标所代表的数是否被用过int n;int su(int n)//判断素数{int i;for( i=2;i<=sqrt(n);i++){if(n%i==0)break;}if(i<=sqrt(n))return 0;elsereturn 1;}int dfs(int s){if(s==n&&su(a[0]+a[n-1]))//当s==n时,也就是a数组以0到n-1为下标的空间已经有数,或者说现在是一条长链,</strong></span>
<span style="font-size:18px;"><strong>                                 //如果第一个和最后一个数的和是素数,就可以组成一个素数环,循环输出a数组即可。</strong></span>

<strong><span style="font-size:18px;">{for(int j=0;j<n;j++){printf("%d ",a[j]);}printf("\n");return 1;}for(int k=2;k<=n;k++){if(b[k]==0&&su(k+a[s-1]))//找一个没有被用过的数,并且此数和上一个数的和是素数{a[s]=k;//把这个数存入,也就是把此数加入素数环b[k]=1;//标记此数已经被用过dfs(s+1);//本阶段已经做完,寻找下一个数b[k]=0;//释放标记,不干扰下一次}}}int main(void){int count;//作为题目要求的Case 的计数器count=1;while(scanf("%d",&n)!=EOF){if(n==0)//要求以0作为程序的结束return 0;memset(a,0,sizeof(a));//其实此数组不置为0也可以,因为会直接覆盖memset(b,0,sizeof(b));//此数组要置为0a[0]=1;//素数环的起点是1printf("Case %d:\n",count);if(n%2==0||n==1)//运用上面提到的规律{dfs(1);//从1开始        }else if(n%2!=0)printf("No Answer\n");count=count+1;}</span><span style="font-size: 14px;">return 0;}</span></strong>
0 0
原创粉丝点击