例题7-4 UVA524 Prime Ring Problem(28行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题7-4 UVA524 Prime Ring Problem(28行AC代码)

题目大意

给定n个数,标号为1,2,3,…,n,问n个数能否构成这样一个环:任意两个相邻数和为素数

思路分析

本质是求2~n的全排列,在构造过程中利用相邻和为素数进行剪枝

因为n最大为16,两数之和最大为31,因此可手动写出2~31的素数,便于查询

AC代码(C++11,全排列+剪枝)

#include<bits/stdc++.h>
using namespace std;
unordered_set<int> prime{2,3,5,7,11,13,17,19,23,29,31}; // 32内的素数
int n, vis[20]={0}, kcase=0;
vector<int> ans{1}; // 1先置入
void dfs(int cnt) { // cnt表示目前排列中已枚举的个数
    if (cnt == n && prime.count(1+ans.back())==1) { // 找到结果
        for (int i=0; i < ans.size(); i ++) printf("%d%s", ans[i], i == ans.size()-1 ? "\n" : " ");
    }
    else {
        for (int i=2; i <= n; i ++) { // 枚举2~n的全排列
            if (vis[i] == 0 && (prime.count(i+ans.back()) == 1)) { // 剪枝
                ans.push_back(i); vis[i] = 1; // 保存结果,标记已访问
                dfs(cnt+1); // 下一个
                ans.pop_back(); vis[i] = 0; // 退出最后一个结果,标记为未访问(回溯过程)
            }
        }
    }
}
int main() {
    while (scanf("%d", &n) == 1) {
        memset(vis, 0, sizeof(vis)); // 初始化
        if (kcase != 0) puts("");
        printf("Case %d:\n", ++kcase);
        dfs(1);
    }
    return 0;
}
发布了128 篇原创文章 · 获赞 87 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40738840/article/details/104449317
今日推荐