Prime Ring Problem

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章