之前全排列都是用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");
}