/*
素数环:
步骤
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;
}
算法设计与分析:第五章 回溯法 5.4素数环
原文作者:回溯法
原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/47189417
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/47189417
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。