杭电OJ 1016 Prime Ring Problem

来源:互联网 发布:精通qt4编程 源码 编辑:程序博客网 时间:2024/05/21 19:50

Prime RingProblem

Problem Description

A ring is composeof n circles as shown in diagram. Put natural number 1, 2, ..., n into eachcircle separately, and the sum of numbers in two adjacent circles should be aprime.

Note: the number of first circle should always be 1.

 

 

Input

n (0 < n <20).

 

 

Output

The output formatis shown as sample below. Each row represents a series of circle numbers in thering beginning from 1 clockwisely and anticlockwisely. The order of numbersmust satisfy the above requirements. Print solutions in lexicographical order.

You are to write a program that completes above process.

Print a blank line after each case.

 

 

Sample Input

6

8

 

 

Sample Output

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

 

 

解题思路:

         由于2<n<20,因此任意相邻两个位置之和大于2,小于40,所有相邻两个位置的数字之和一定是40以内的素数,并且一定是奇数(因为大于2)。

         这里又可以发现,由于任意相邻两个数字之和一定是奇数,因此素数环上的数字一定奇偶交替排列,不可能出现相邻两个位置都是奇数,或者都是偶数的情况出现。要使得素数环可以形成,n一定是偶数!否则一定会出现相邻两个位置同是奇数,或同是偶数的情况发生。

         这道题只需要考虑n为偶数的情况即可。具体实现方法就是穷举,可以用深度优先搜索算法来实现。

代码如下:

#include <stdio.h>int book[40],ring[21];int testprime[40];/*ring数组用来表示所要给出素数环*/void dfs(int step, int n);int main(){int n,i,j,num=0;/*先筛选2到40以内的素数,如果i(1<i<40)是素数,testprime[i]=0否则testprime[i]=-1*/for(i=2;i<40;i++){/*i从2开始一直筛选到40*/if(testprime[i]==0){/*素数筛法,将i的倍数都标记为合数,最终只留下素数*/for(j=i*i;j<40;j+=i){testprime[j]=-1;}}}while(scanf("%d",&n)!=EOF){    num++;        ring[1]=1;/*素数环的第一个位置固定为1*/        printf("Case %d:\n",num);/*根据分析,只有n为偶数时,素数环才存在,因此只要对n为偶数的情况进行搜索*/if(n%2==0) dfs(2,n);//从第二个位置ring[2]开始搜索        printf("\n");}return 0;}/*深度优先搜索,从第二个位置开始*/void dfs(int step, int n){int i;if(step==n+1) {/*给出一种排列情况后,如果圆环的头部ring[1]和尾部ring[n]之和也为素数,输出这组符合条件的解*/if(testprime[ring[1]+ring[n]]==0){for(i=1;i<n;i++)printf("%d ",ring[i]);printf("%d\n",ring[i]);}return;}    for(i=2;i<=n;i++)   /*从第二个位置开始,每个位置可能放置的数是2,3,...,n*/    {        if(book[i]==0 && testprime[ring[step-1]+i]==0) /*如果i之前没有被放置,并且和前一个数之和是素数当前位置就放置数字i*/        {            book[i]=1;            ring[step]=i;            dfs(step+1,n);  //递归进行下一个位置的搜索            book[i]=0;  //完成上一个搜索后,回收数字i        }    }return;}


0 0