题解
【提高】素数环2
1 条题解
-
0
#include<bits/stdc++.h> using namespace std; int n, a[21];//n是输入的数,a存素数环里的数字 bool f[21];//f[i]标记数字i有没有被用过 int c = 0;//c记录已经输出的方案数,最多出10个 //判断x是不是素数 bool p(int x) { if (x <= 1) return false;//1和比1小的都不是素数 if (x == 2) return true;//2是素数 if (x % 2 == 0) return false;//大于2的偶数不是素数 //只拿奇数试除,节省时间 for (int i = 3; i * i <= x; i += 2) { if (x % i == 0) return false; } return true; } //打印一组合法素数环 void pr() { //没凑够10组才打印 if (c < 10) { for (int i = 1; i <= n; i++) { cout << a[i] << " "; } cout << endl; c++;//打印完方案数量加1 } } //k代表现在要填第k个位置 void d(int k) { if (c >= 10) return;//够10个方案直接停止搜索 //k大于n,所有位置全部填完 if (k > n) { //圆环要求最后一位和第一位相加也是素数,合格才打印 if (p(a[n] + a[1])) pr(); return; } int s; if (k == 1) { s = 1;//第一个位置只能选1 } else { s = 2;//后面位置从2开始选数 } for (int i = s; i <= n; i++) { if (!f[i]) {//数字i还没被使用 //是第一位 或者 和前一个数相加是素数,才能放进去 if (k == 1 || p(a[k-1] + i)) { a[k] = i;//把i放到第k个位置 f[i] = true;//标记i已经被占用 d(k + 1);//递归填下一个位置 f[i] = false;//回溯,取消标记,换别的数字尝试 if (c >= 10) return;//中途凑够10组直接退出 } } } } int main() { cin >> n; //单独处理n=1的特殊情况 if (n == 1) { cout << "1\n"; return 0; } //大于1的奇数无法组成素数环,直接结束不搜索 if (n % 2 == 1 && n > 1) return 0; d(1);//从第一个位置开始回溯搜索 return 0; }
- 1