DFS专练4 素数环问题

来源:互联网 发布:电脑桌面淘宝下载 编辑:程序博客网 时间:2024/05/25 20:01
题意:

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。
为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。
输入

有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出

如果存在满足题意叙述的素数环,从小到大输出。
否则输出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
————————————————————————————————————————————————————————————————————————————
分析:1.只有奇数才可能是素数,而奇数=偶数+奇数,所以素数环一定是奇数偶数相间分布,所以n一定是偶数,如果是奇数那一定存在两奇数相邻情况。
2.在偶数的前提下,因题目说“小到大输出”所以输出的第一位肯定是1,所以可以按照第一位放置1,后面DFS,然后判断未被标记的同时判断该数与上一个已放置的数和是否是素数,是则可以放,最后放完最后一个数判断Memory[n-1]+1是否为素数即可输出。
3.特殊情况处理:n==1时,输出自己即可
4.与全排列类似,只不过DFS时减少了循环,增加了判断
5.常量数组的应用,因最多n=20,n+n最多=40,所以可以把是否素数保存下来直接判断即可!
#include <stdio.h>int Prime[40]= {1,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0};//常量数组判断素数,素数为1否则为0int Memory[20];//存储结果int Input[20];//存储输出固定位置int sign[20];//标记该数字是否放置了int n;void DFS(int k){    int i;    if(k==n)//结束条件,数字都放置完    {        if(Prime[Memory[n-1]+Memory[0]-1]==1)//追加判断:素数环尾部与头部和也为素数        {            for(i=0; i<n; i++)            {                if(i==0)                    printf("%d",Memory[i]);                else                    printf(" %d",Memory[i]);            }            printf("\n");        }        return;//回溯    }    for(i=1; i<n; i++)//i从1开始,而不是0了 因为1已经被固定在Memory[0]了    {        if(sign[i]==0&&Prime[Input[i]+Memory[k-1]-1]==1)//未被标记同时判断与前一个数的和是否为素数        {            Memory[k]=Input[i];//放置            sign[i]=1;//标记            DFS(k+1);//DFS探索下一层            sign[i]=0;//回溯        }    }}int main(){    int t=0;    while(scanf("%d",&n)!=EOF&&n)    {        t++;        memset(sign,0,sizeof(sign));        memset(Memory,0,sizeof(Memory));        memset(Input,0,sizeof(Input));        int i;        printf("Case %d:\n",t);        if(n==1)        printf("1\n");//特殊情况        else if(n%2!=0)//奇数排除        printf("No Answer\n");        else        {            for(i=0; i<n; i++)                Input[i]=i+1;            Memory[0]=1;//存放1            DFS(1);//从1开始        }    }    return 0;}