之前全排列都是用next_permutation(), 没自己写过。 看到全排列就想逃避。
急着去看解题报告, 没完全看完就想自己写, 结果写的过程中报告的思路跟自己的思路乱成一团。。
所以: 1. 依赖库函数的前提是, 自己能写出来这样的函数
2.要嘛不看解题报告, 要嘛就完全看完、看懂了再自己写。
素数环:相邻两个数的和为素数 用DFS + 回溯
#include <stdio.h>
#include <string.h>
#define PRIME 1
#define NOT_PRIME 0
#define MAX_N 20 + 1
#define PRIME_NUM 13
int n;
int mapPrime[MAX_N + MAX_N];
int ring[MAX_N];
void outPut();
void DFS(int);
bool ok(int, int);
int main()
{
int cases = 1;
//生成素数表 虽然不优雅, 但是速度快
memset(mapPrime, NOT_PRIME, sizeof(mapPrime));
mapPrime[ 2]=mapPrime[ 3]=mapPrime[ 5] = PRIME;
mapPrime[ 7]=mapPrime[11]=mapPrime[13] = PRIME;
mapPrime[17]=mapPrime[19]=mapPrime[23] = PRIME;
mapPrime[27]=mapPrime[29]=mapPrime[31] = PRIME;
mapPrime[37] = PRIME;
while (scanf("%d", &n) != EOF) {
ring[1] = 1;
printf("Case %d:\n", cases++);
DFS(2);
printf("\n");
}
return 0;
}
void DFS(int cur)
{
for (int i = 2; i <= n; i++) { //放置第i个元素
if (ok(cur, i)) {
ring[cur] = i;
if (cur == n) { //序列完成, 打印
outPut();
}else { //否则继续放置
DFS(cur + 1);
ring[cur] = 0;
}
}
}
}
bool ok(int cur, int next)
{
//这个数字出现过?
for (int i = 1; i < cur; i++) {
if (ring[i] == next || ring[i] == 0) {
return false;
}
}
//能形成素数环?
if (cur < n) {
if (mapPrime[ring[cur - 1] + next] == 0) {
return false;
}
}else {
return (mapPrime[ring[1] + next] && mapPrime[ring[cur - 1] + next]);
}
return true;
}
void outPut()
{
printf("1");
for (int i = 2; i <= n; i++) {
printf(" %d", ring[i]);
}
printf("\n");
}