素数环

来源:互联网 发布:在ubuntu上下载软件 编辑:程序博客网 时间:2024/05/22 09:40

问题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=488
素数环
时间限制: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

问题分析:
当n=1时,答案为1
当n为奇数时,一定无解。因为n为奇数,则必有两个奇数会相邻(偶数必奇数少,不能把所有奇数用偶数分割开),则和为偶数,偶数一定不是素数(除了2)。因此一定找不到一个序列满足素数环。
当n为偶数时,采用深度搜索的方法,第一个环始终填1,从第二个环开始,每个环都尝试其余的n-1个数字,利用递归对所有情况进行遍历。再遍历时利用相邻两环之和为素数进行剪枝,当深度达到n时,即最后一个环也填了之后,进行判断是否最后一个和第一个环之和为素数。是则进行输出,否则返回上层即可。

代码:

#include <iostream>#include <stdio.h>#include <string.h>#define MAX 21/* run this program using the console pauser or add your own getch, system("pause") or input loop */int circle[MAX];int mark[MAX];  //标记数字是否已经使用过 int n;  //素数环的大小int prime[MAX]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53, 59, 61 ,67 ,71 };   //预先存储素数 int length = 20;  //素数的个数 bool isPrime(int x) {    for(int i=0;i<length;i++){        if(x == prime[i]) {            return true;        }    }    return false;}void dfs(int k) {    //printf("%d\n",k);    if(k == n){        if(isPrime(circle[0]+circle[k-1])== false){            return;        }        //进行输出        int i;        for(i=0;i<n-1;i++) {            printf("%d ",circle[i]);        }        printf("%d",circle[i]);        printf("\n");        return;    }    for(int i=2;i<=n;i++){        if(mark[i] == false && isPrime(circle[k-1]+i)){            mark[i] = true;            circle[k] = i;            dfs(k+1);            //递归返回时要重置数字i为未使用             mark[i] = false;        }    }}int main(int argc, char** argv) {    int ca = 1;     while(scanf("%d",&n)) {        printf("Case %d:\n",ca++);        if(n%2 == 0){            circle[0]=1;            memset(mark,false,sizeof(mark));            dfs(1) ;            }else if(n == 1){            //不存在偶数个素数的素数环             printf("1\n");        }else{            printf("No Answer\n");        }    }    return 0;}
原创粉丝点击