hdu1016 Prime Ring Problem 素數環

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1016


題目大意:

一道關於求素數環的問題,輸入一個數字n,按字典序輸出從1到n的所有可以連成素數環串。

解題思路:

素數環的定義是將從1到n這n個整數圍成一個圓環,若其中任意2個相鄰的數字相加,結果均爲素數,那麼這個環就成爲素數環。例如:當n爲10時,序列:1 2 3 8 5 6 7 10 9 4 就可以形成一個素數環。

素數環的生成可以用深搜來實現,素數用素數篩來打表,再用一個布爾型數組來記錄一個數字是否被訪問過。需要注意的是標記數字的回溯和首尾的數字和也應爲素數,然後控制格式輸出就可以了。

代碼:

/*
     ID: Code-Cola
     PROG: 1016
     LANG: C++
*/

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

/********** 全局變量 **********/

int n;
int a[25];                                       //存儲生成的序列
bool k[25];                                      //記錄某個數字是否被訪問過
bool pk[40];                                     //素數判定
int p[12];

/********** 函數聲明 **********/

void dfs(int t);                                 //搜索函數
void prime();                                    //素數篩
bool Is_prime(int x);                            //素數判定

int main()
{
    int i = 1;
    prime();
    while (~scanf("%d",&n)) {
        printf("Case %d:\n",i++);
        memset(k, 1, sizeof(k));                 //初始化爲true
        a[0] = 1;
        dfs(1);                                  //進行深搜
        cout << endl;
    }
}

void dfs(int t)
{
    int i;
    if (t == n && Is_prime(a[n - 1] + a[0])) {   //判斷首尾數字和
        printf("%d",a[0]);
        for (i = 1; i < n; i++) {
            printf(" %d",a[i]);                  //控制格式輸出
        }
        printf("\n");
        return;
    }
    for (i = 2; i <= n; i++) {
        if (k[i] && Is_prime(i + a[t - 1])) {
            a[t] = i;
            k[i] = false;
            dfs(t + 1);                          //遞歸
            k[i] = true;                         //回溯
        }
    }
}

void prime()                                     //素數篩
{
    memset(pk, 0, sizeof(pk));
    int i,j,num = 0;
    p[num++] = 2;
    pk[0] = pk[1] = pk[4] = true;
    for (i = 3; i < 40; i += 2) {
        if (!(pk[i]))
            p[num++] = i;
        for (j = 1; j < num && i * p[j] < 40; j++) {
            pk[i * p[j]] = 1;
            if (!(i % p[j]))
                break;
        }
    }
}

bool Is_prime(int x)
{
    return (x & 1) || x == 2 ? !pk[x] : false;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章