一道经典的算法题。链接:https://onlinejudge.org/external/5/524.pdf

这里的原题的描述,我们需要注意的只有输入和输出的格式那里,对于题意的理解,书中的中文描述已经足够了,因为题意是比较简单的。(这里可以去书上读一下题目的意思。)

首先,素数的定义:wiki

大于 1 的自然数中,除了 1 和该数自身外,无法被其他自然数整除的数。(2 当然是素数。)

关于输出中的数字排列的顺序,书上说是逆时针排列,而原题中说的是顺时针和逆时针,这个其实无所谓,我们依次 dfs 过去,最终会把顺时针和逆时针的情况全部囊括的。

然后,书上首先介绍了一个“生成-测试”法,这个比较容易,这里就不去详细说明,我们就简单看下用到的 next_permutation 这个函数,可以看一下文档

核心的部分是这个 dfs,

 1/*
 2  从 1 开始,依次去搜索每个位置上的可能性
 3
 4  cur: 当前的位置
 5*/
 6void dfs(int cur) {
 7  if (cur == n && isp[A[0] + A[n - 1]]) { // 递归边界
 8    for (int i = 0; i < n; i++) {
 9      if (i != 0)
10        printf(" ");
11      printf("%d", A[i]);
12    }
13    printf("\n");
14  } else
15    for (int i = 2; i <= n; i++)
16      if (!vis[i] && isp[i + A[cur - 1]]) { // 判断当前的数字是否可行,不行的就跳过,相当于是剪枝了
17        A[cur] = i;
18        vis[i] = 1;   // 标记已经访问过
19        dfs(cur + 1); // 递归处理下一个位置
20        vis[i] = 0;   // 还原
21      }
22}

我们直接看所有的代码,一次性整体进行讲解。