题目描述
输入一个正整数n,将从1到n这n个整数围成一个圆环,如果其中任意2个相邻的数字相加结果均为素数,那么这个环就称为素数环。
输入
输入一个正整数n,n<=16
输出
输出长度为n的素数环序列(可能的解有多个),要求从整数1开始逆时针排列,同一个环恰好输出一次。
样例输入
6
样例输出
1 4 3 2 5 6 1 6 5 2 3 4
提示
回溯法
#include <stdio.h>
#include <string.h>
int isprime[33] = {0}, prime[33] = {0}, cnt = 0;
void eular(int n) { //欧拉筛
memset(isprime, 0, sizeof(isprime)); //0是素数1不是
isprime[1] = 0;
for (int i = 2; i < n; i++) {
if (isprime[i] == 0)
prime[++cnt] = i;
for (int j = 1; j <= cnt && i * prime[j] <= n; j++) {
isprime[i * prime[j]] = 1;
if (i % prime[j] == 0)
break;
}
}
}
int a[20];//用于存储该串
int bol[20] = {0}; //判断走没走过
int n;
void dfs(int u) { //回溯法
if (u == n + 1) {
for (int i = 1; i <= n; i++)
printf("%d%c", a[i], " \n"[i == n]);
return;
}
for (int i = 2; i <= n; i++) {
if (u == n) { //最后一个数与第一个数特判
if (!isprime[i + a[1]] && !bol[i] && !isprime[i + a[u - 1]]) {
bol[i] = 1;
a[u] = i;
dfs(u + 1);
bol[i] = 0;
a[u] = 0;
}
}
if (u != n && !isprime[i + a[u - 1]] && !bol[i]) { //当前的数与前一个数相加为素数且该数不与其他重复
bol[i] = 1;
a[u] = i;
dfs(u + 1);
bol[i] = 0;
a[u] = 0;
}
}
}
int main() {
scanf("%d", &n);
a[1] = 1;
bol[1] = 1;
eular(n + n);
dfs(2);
}