#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 判断一个数是否为素数
bool isPrime(int num) {
if (num <= 1) {
return false;
}
for (int i = 2; i * i <= num; ++i) {
if (num % i == 0) {
return false;
}
}
return true;
}
// 判断两个数的和是否为素数
bool isSumPrime(int a, int b) {
int sum = a + b;
return isPrime(sum);
}
// 回溯函数,用于搜索摆放环的方式
void backtrack(vector<int>& nums, vector<bool>& visited, vector<int>& path, vector<vector<int>>& res) {
if (path.size() == nums.size()) { // 找到一个解,加入结果集
res.push_back(path);
return;
}
int prev = path.empty() ? -1 : path.back();
for (int i = 0; i < nums.size(); ++i) {
if (!visited[i] && (prev == -1 || isSumPrime(nums[i], prev))) { // 满足相邻两个数的和是素数的条件
visited[i] = true;
path.push_back(nums[i]);
backtrack(nums, visited, path, res); // 继续搜索下一个位置
visited[i] = false;
path.pop_back(); // 恢复状态,进行下一个尝试
}
}
}
// 寻找从1到n这n个数组成的满足条件的环
vector<vector<int>> findPrimeCircle(int n) {
vector<vector<int>> res;
vector<int> nums(n);
for (int i = 0; i < n; ++i) {
nums[i] = i + 1;
}
vector<bool> visited(n, false); // 记录数字是否已经被访问过
vector<int> path; // 用于存放当前的路径
backtrack(nums, visited, path, res);
return res;
}
int main() {
int n;
cin >> n;
vector<vector<int>> circles = findPrimeCircle(n);
cout << "围成的圈是: ";
for (const auto& circle : circles[0]) {
cout << circle << " ";
}
cout << endl;
return 0;
}
这是一个使用递归回溯算法寻找满足条件的环的代码实现。首先定义了两个辅助函数:
isPrime
函数用于判断一个数是否为素数。isSumPrime
函数用于判断两个数的和是否为素数。
然后,在回溯函数 backtrack
中,我们通过不断尝试每个位置上可选的数字,并判断其与前一个数字之间的和是否为素数。如果满足条件,则继续向下一步搜索;否则进行下一个尝试。
最后,在主函数中调用 findPrimeCircle
函数来寻找从1到n这n个数字组成满足条件的环。将结果保存在二维向量 circles
中,并输出第一个解。
根据题目描述,输入20时预期输出为围成的圈是: 1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18。
内容由零声教学AI助手提供,问题来源于学员提问