Prime Ring Problem

来源:互联网 发布:家庭千兆网络组建方案 编辑:程序博客网 时间:2024/05/17 11:32

Prime Ring Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 29687    Accepted Submission(s): 13241


Problem Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.

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


 

Input
n (0 < n < 20).
 

Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must 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
68
 

Sample Output
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 2
 

Source
Asia 1996, Shanghai (Mainland China)
思路:下面这个程序是我之前写的,超时了,思路可能就是大众思路,next_permutation函数,所给的数排列,连续两个数判断是不是素数,是的话,计数加1,还有最后一个数和第一个数加在一起判断是不是素数,是计数加1,最后计数和这些数个数相等时,说明构成的是素数环。但是这是超时的。。所以该怎么办呢。。上网搜了一下,这是一道深搜dfs问题,我只能说关于dfs自己根本不会写,看别人代码,用很长时间才能明白什么意思,这类题型还是很生的。这道题深搜,大意是:
例如:n=4,先判断2访问过没有并且2加p[0](即是1)是不是素数,如果是的话,就把2赋给p[1],2标记为已访问,然后再调用dfs(2,4),此时2已被访问过,就判断3,没访问,而且3+p[1]是素数,把3赋给p[3],3被标记,调用dfs(3,4),2,3都已经访问,判断4,4<=4,然后4+p[2]仍是素数,那么把4赋给p[3],标记访问过,调用dfs(4,4)此时,再判断p[0]与p[n-1],仍是素数,那么就输出1 2 3 4。因为2,3,4都被访问过,所以dfs(4,4)调用结束,4恢复没有被标记。接着是1,2,4(不满足),
1,3(不满足)1,4,2(不满足)1,4,3,2(满足)输出。这个dfs方法比较抽象。。
参考博客来源:http://blog.csdn.net/niushuai666/article/details/7365189
代码如下(2个):
#include<iostream>//超时代码my code
#include<stdio.h>#include<algorithm>#include<cmath>using namespace std;int sushu(int x){    if(x==2||x==3)         return 1;    if(x==1)        return 0;    int i,pan=0;    for(i=2;i<x;i++)    {        if(x%i==0)        {            pan=1;            break;        }    }    if(pan==0)        return 1;    else        return 0;}int main(){    int n,i,ji=1;    int a[20];    while(~scanf("%d",&n))    {        printf("Case %d:\n",ji++);        for(i=0;i<n;i++)            a[i]=i+1;        do        {            int count=0;            if(a[0]==1)            {                for(i=0;i<n-1;i++)                {                if(sushu(a[i]+a[i+1]))                       count++;                }                if(sushu(a[0]+a[n-1]))                  count++;                if(count==n)                {                for(i=0;i<n-1;i++)                    cout<<a[i]<<" ";                cout<<a[i]<<endl;                }            }            else                break;        }while(next_permutation(a,a+n));        cout<<endl;    }    return 0;}
<pre class="cpp" name="code">#include<iostream>//dfs深搜ac代码 my codeinclude<stdio.h>#include<math.h>#include<string.h>using namespace std;    bool isprime[40];int visited[40];int p[40]={1};void dfs(int start,int n){    int i;    if(start==n && isprime[p[0]+p[n-1]])    {        for(i=0;i<n-1;i++)            cout<<p[i]<<" ";        cout<<p[i]<<endl;    }    for(i=2;i<=n;i++)      {        if(!visited[i] && isprime[i+p[start-1]])        {            visited[i]=1;              p[start]=i;            dfs(start+1,n);          
            visited[i]=0;             }    }}int main(){    memset(isprime,true,sizeof(isprime));                 int i,j,d,n,count=1;   d=static_cast<int>(sqrt(40.0));  isprime[0]=false;isprime[1]=false;   for(i=2;i<d;i++)   { if(isprime[i])          for(j=i*i;j<40;j+=i)            isprime[j]=false;   }    while(scanf("%d",&n)!=EOF)    {            memset(visited,0,sizeof(visited));        printf("Case %d:\n",count++);             int start=1;        if(n==1)        {            cout<<"1"<<endl;            continue;        }        if(n&1)            continue;         dfs(start,n);        cout<<endl;    }    return 0;}

0 0