0
点赞
收藏
分享

微信扫一扫

【算法】回溯法——素数环问题(C语言)

大南瓜鸭 2022-01-15 阅读 201

题目: 把从1到n这n个数摆成一个环,要求相邻两个数的和是一个素数,求出所有解法。

思路:
用数组a模拟n个数组成的环。

递归地填数:
判断第 k 种可能是否合法,
如果合法则填数;判断是否到达目标(n个数已填完),是则输出,不是则递归填下一个
如果不合法则选择下一种可能;

完整代码+注释

# include<stdio.h>
# include<math.h>

int a[20];						//用数组模拟n个数组成的环

int check_1(int x, int i);		//判断数是否重复
int check_2(int x);				//判断一个数是否为素数
int check_3(int x, int i);		//判断相邻两数之和是否为素数
void Output_Num();				//输出函数
int n, count = 0;

/*填数,填第i+1个数(i从0开始)*/
void Insert_Num(int i) {
	int k;
	for (k = 2; k <= n; k++) {
		if (check_1(k, i) && check_3(k, i)) {
			a[i] = k;			//符合条件则将数k填入a数组中
			if (i == n - 1) {
				Output_Num();	//满n个数(i从0开始)则填数完成,输出
				count++;
			}
			else {
				Insert_Num(i + 1);	//填下一个数
				a[i] = 0;			//回溯,置a[i]=0
			}
		}
	}
}

/*判断数x是否与数组a中前i个元素重复*/
int check_1(int x, int i) {
	int k;
	for (k = 0; k < i; k++) {
		if (a[k] == x)
			return 0;
	}
	return 1;
}

/*判断数x是否为素数*/
int check_2(int x) {
	int k, a;
	a = sqrt(x);
	for (k = 2; k <= a; k++) {
		if (x % k == 0)
			return 0;
	}
	return 1;
}

/*判断数x和它相邻的前一个数a[i-1]之和是否为素数*/
int check_3(int x, int i) {
	if (i < n - 1)
		return (check_2(x + a[i - 1]));
	else
		return (check_2(x + a[i - 1]) && check_2(x + a[0]));
		//最后一个数还需判断和第一个数之和是否为素数
}

/*输出函数,打印素数环*/
void Output_Num() {
	for (int j = 0; j < n; j++)
		printf("%d ", a[j]);
	printf("\n");
}

int main() {
	int k;
	printf("请输入n:");
	scanf("%d", &n);
	for (k = 0; k < n; k++)
		a[k] = 0;			//初始化为0
	a[0] = 1;				//第一个数放1

	Insert_Num(1);			//调用函数填第二个数

	if (count == 0)
		printf("\nNo Answer!\n");
	else
		printf("\n共有%d种解法\n", count);
	return 0;
}

运行结果
(1)n=8时
n=8时(2)n=10时
n=10时

举报

相关推荐

0 条评论