算法设计与分析:第五章 回溯法 5.4素数环

/*
素数环:
步骤
1初始化
2递归填数

输入:
6
8
输出
case1
1 4 3 2 5 6
1 6 5 2 3 4
case2
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
*/

#include <iostream>

using namespace std;

bool isRepeat(int k , int pos, int* x)
{
	for(int i = 1 ; i < pos ; i++)
	{
		//如果前面的数与当前数字相同,待比较的数字是k
		if(x[i] == k)
		{
			return true;
		}
	}
	return false;
}

bool isPrime(int i)
{
	int k = (int)sqrt(i);
	for(int j = 2 ; j <= k ; j++)
	{
		if(i % j == 0)
		{
			return false;
		}
	}
	return true;
}

bool isSumPrime(int pos , int* x , int n , int k)
{
	//如果没有达到n,只需要正常检查
	if(pos < n)
	{
		//直接用k进行尝试,而不是x[k]
		if(isPrime(k + x[pos - 1]))
		{
			return true;
		}
	}
	else
	{
		//还要检查第一个和最后一个
		if(isPrime(k + x[pos - 1]) && isPrime(k + x[1]))
		{
			return true;
		}
	}
	return false;
}


void primeCircle(int pos , int n , int& iCount , int* x)
{
	//对2~20号数字进行尝试
	for(int k = 2 ; k <= n ; k++)
	{
		//检查数字是否重复,判断相邻和是否为素数
		if(!isRepeat(k , pos , x) && isSumPrime(pos, x , n , k))
		{
			x[pos] = k;
			if(pos == n)
			{
				for(int p = 1 ; p <= n ; p++)
				{
					cout << x[p] << "\t" ;
				}
				cout << endl;
				iCount++;
			}
			//尝试下一个数
			else
			{
				primeCircle(pos+1 , n ,iCount , x);
				//回溯,清理现场。但是这里并没有做
				x[pos] = 0;
			}
		}
	}
}



void process()
{
	int n ;
	int x[100];
	while( cin >> n)
	{
		int iCount = 0;
		int pos = 2;
		memset(x, 0 , sizeof(x));
		x[1] = 1;//初始化
		memset(mark , 0 , sizeof(mark));//初始化访问标记
		mark[1] = true;
		primeCircle(pos , n , iCount , x);
		cout << iCount << endl;
	}
}

int main(int argc, char* argv[])
{
	process();
	getchar();
	return 0;
}

    原文作者:回溯法
    原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/47189417
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞