素數環 DFS 回溯

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章