素数环 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");
}


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