Prime Ring Problem

来源:互联网 发布:mysql多主键 编辑:程序博客网 时间:2024/05/16 07:34

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

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
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

渣渣总是需要参考别人代码。。。。

#include<stdio.h>#include<string.h>#include<math.h>int a[22],w[22],n;int issushu(int x){    int c=(int)(sqrt(x));    for(int i=2;i<=c;i++)    {        if(x%i==0)          return 0;    }    return 1;}//看题目的输入范围,1 < N < 20,由于输入规模比较小,所以考虑使用查表法来判定素数,查表法是典型的以空间换时间的方法。20以内两个数之和最大是18 + 19 = 37,而37以内的素数分别是23571113171923293137,我们可以定义一个38个元素的数组,当i为素数时,令a[i] = 1,否则a[i] = 0。这样,要判断一个数是否为素数时,直接判断a[i]是否为1即可,省了时间//int p[38]//{//  0,0,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,//};void dp(int m){    if(m==n+1)    {        for(int i=1;i<n;i++)        printf("%d ",a[i]);        printf("%d\n",a[n]);    }    else    {        for(int j=2;j<=n;j++)        {            if(issushu(j+a[m-1])&&w[j]!=1)//p[j+a[m-1]]==1            {                w[j]=1;                a[m]=j;                if((m==n&&issushu(a[1]+a[n]))||m!=n)//p[a[1]+a[n]]==1                    dp(m+1);                w[j]=0; //这点不可以写在if语句之中            }           }    }   }int main(){    int k=1;    while(~scanf("%d",&n))    {        memset(a,0,sizeof(a));        memset(w,0,sizeof(w));        a[1]=1;        w[1]=1;        printf("Case %d:\n",k++);        if(n==1)        {            printf("1\n\n");            continue;        }        if(n%2==1)        {            printf("\n");            continue;        }        //考虑输入的特点,如果输入N是奇数的话,由于起点从1开始,那么1-N之一个,那么把这N个数排成一个环,根据鸽巢原理,必然有两个奇数是相邻的,而两个奇数之和是偶数,偶数不是素数,所以我们得出结论,如果输入N是奇数的话,没有满足条件的排列。这样当N是奇数的时候,直接返回即可。如果1-N之间每个数输入的几率相同,这个判断可以减少一半的计算量。        dp(2);        printf("\n");    }    return 0;}
0 0
原创粉丝点击