题目大意:
输入一个数,输出以1为开头相邻两个数的和为素数的数列。值得注意的是这个数列是一个环
, 所以头尾相加也为素数。
思路
回溯,相当于深度遍历一个解答树,可以有效的减少枚举量。
总结
第一次做回溯的题,看了紫书还是半懂半不懂,还是得多练多想。
#include <stdio.h>
#include <string.h>
#define N 16
int kase = 0;
int n;
int isp[N*2] = {0};
int A[N] = {1};
int vis[N];
int is_prime(int n) {
for(int i = 2; i * i <= n; i++)
if (n % i == 0) return 0;
return 1;
}
void create_prime_num_list() { //生成素数表,方便查表
for(int i = 2; i < N*2; i++)
if (is_prime(i)) isp[i] = 1;
}
void dfs(int cur) {
if (n == cur && isp[A[0] + A[n - 1]]) {
for(int i = 0; i < n; i++) {
if (i == 0) printf("%d", A[i]);
else printf(" %d", A[i]);
}
printf("\n");
}
else {
for(int i = 2; i <= n; i++) {
if (!vis[i] && isp[A[cur - 1] + i]) {
A[cur] = i;
vis[i] = 1;
dfs(cur + 1);
vis[i] = 0;
}
}
}
}
int main() {
//freopen("input.txt", "r", stdin);
create_prime_num_list();
while(~scanf("%d", &n)) {
memset(vis, 0, sizeof(vis));
if (++kase == 1) printf("Case %d:\n", kase);
else printf("\nCase %d:\n", kase);
dfs(1);
}
return 0;
}