这题是一道深搜的题目,题意是给你一个n,让你寻找一个环,环中的相邻数字相加是素数,且要用尽所有的数。
输出即按照字典序,输出所有的可能。
这题的话,我们搜索的下一个状态就是升序的1~n中的数字,递归的边界条件就是第n个数字和第一个数字相加为素数。
我们进入递归的条件就是如果我们还没使用过这个数字,并且它和上一个数相加是素数,我们就递归搜索它,然后回溯。
我们要想使环中的相邻数字相加为素数,当我们按照顺序,使它和它的上一个数字相加为素数的时候,这个条件就满足了。
而且进入之后第n个数字恰好没有和第一个数字进行判断,所以就进入了我们的边界条件。
按照字典序的升序进行输出,我们搜索的时候就按照字典序去搜索,进入深搜的数字自然就是字典序的升序了,输出也是如此。
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int prime[45], vis[25], a[25];
int n, Case=1;
void dfs(int num)
{
if (num==n&&prime[a[num-1]+a[0]]) {
for (int i = 0; i < num - 1; i++)
printf("%d ", a[i]);
printf("%d
", a[num - 1]);
}
else {
for (int i= 2; i <= n;i++) {
if (!vis[i]&&prime[a[num-1]+i]) {
vis[i] = 1;
a[num++] = i;
dfs(num);
vis[i] = 0;
num--;
}
}
}
}
int main()
{
fill(prime, prime + 45, 1);
for (int i = 2; i < 41; i++) {
for (int j = 2; j <= sqrt(i); j++) {
if (i % j == 0) {
prime[i] = 0;
break;
}
}
}
while (scanf("%d",&n)!=EOF) {
printf("Case %d:
", Case ++);
fill(vis, vis + 25, 0);
vis[0] = 1;
a[0] = 1;
dfs(1);
printf("
");
}
return 0;
}