关于素数环,首先要做以下分析:
1.要判断1-n是否能组成素数环
2.如何构成素数环
下面一一分析:
1.根据网上结论当n为偶数(除1之外)时,才能构成素数环.
2.什么是素数环?简单的理解就是:n个数按照一定的顺序围成环,相邻数字之和为素数
(1).每次选中一个数cur,就要检查cur+prev(上次选择的数)是否为素数.
(2).如果当前选中的数不合适就要换下一个数,知道合适为止,此时就要标记这个数
已经使用,然后进入下一层选择,很容易就想到是个深搜.
(3).既然要选数就要用到循环,那么应该怎么循环呢?举个例子:6的素数环,
当已经选择了1,2,5那么下一层应该从哪里开始选取那,因为前面还有3,4
没有用到,而每次进入下层选择的时候,我们是不能确定哪几个数没用到,
那么就应该从头开始遍历(2-n,假设打头的数都是1).
至于如何判断一个数是否为素数,可以采用素数筛选法或者其他的.
源代码:
#include <stdio.h>
#include <memory.h>
int n;
int num[16] = {0, 1};
char vis[16];
bool isprime[100];
void getPrime() // 筛选素数
{
memset(isprime, true, sizeof(isprime));
isprime[0] = isprime[1] = false;
for (int i=2; i<100; ++i)
{
if (isprime[i])
{
for (int j=2*i; j<100; j+=i)
isprime[j] = false;
}
}
}
void dfs(int cur)
{
int i;
if (cur == n) // 当前已经搜完
{
if (isprime[num[cur-1]+1]) // 检查最后一个与1的和是否为素数
{
for (i=0; i<n; ++i)
printf("%2d ", num[i]);
putchar('\n');
}
return;
}
for (i=2; i<=n; ++i)
{
if (!vis[i] && isprime[num[cur-1]+i]) // 未被访问,切上一个与i之和为素数
{
vis[i] = 1; // 标记(为了下一层不访问)
num[cur] = i; // 保存
dfs(cur+1); // 进入下一层
vis[i] = 0; // 取消标记
}
}
}
int main()
{
getPrime(); // 获取素数
memset(vis, 0, sizeof(vis)); // 取消所有标记
n = 10; // 搜10的素数环
num[0] = 1; // 1
dfs(1);
return 0;
}