例题7-4 素数环(Prime Ring Problem, UVa 524)

欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题7-4 素数环(Prime Ring Problem, UVa 524)题目描述

题意解析

输入正整数n,把整数 1 , 2 , 3 , … , n 1, 2, 3,…, n 1,2,3,,n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好输出一次。 n ≤ 16 n≤16 n16

算法设计

枚举1~n所有的排列显然会超时,需要在枚举过程中进行剪枝,即先判断与邻近数字之和是否为素数,如果不是素数,直接舍去当前取值。另外,由于n最大为16,邻近两数之和最大为32,可以直接写出40以内的素数表即可,不必使用筛法。

C++代码

#include <bits/stdc++.h>
using namespace std;
unordered_set<int> prime = {
    
    2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};//素数表
void f(int A[], int n, int index) {
    
    
    if (index == n + 1) {
    
    //边界条件
        if (prime.find(A[1] + A[n]) != prime.end()) {
    
    //A[n]+A[1]是素数
            for (int i = 1; i <= n; ++i)//输出
                printf("%d%s", A[i], i == n ? "" : " ");
            puts("");
        }
        return;
    }
    for (int i = 1; i <= n; ++i)//遍历数字1~n
        if (find(A + 1, A + index, i) == A + index && prime.find(A[index - 1] + i) != prime.end()) {
    
    //如果数字i没取过,且与邻近数字之和是素数
            A[index] = i;
            f(A, n, index + 1);//继续递归
        }
}
int main() {
    
    
    int n, A[20];
    for (int ii = 1; cin >> n; ++ii) {
    
    
        printf("%sCase %d:\n", ii > 1 ? "\n" : "", ii);
        iota(A, A + n + 1, 0);//将数组A值置位0~n
        f(A, n, 2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/100389570
今日推荐