题目要求组成一个素数环,相邻两个相加为素数。按照字典序输出可行的方案。
数据最大是16,显而易见,组成素数环的要求十分苛刻,我们直接手动把可能用到的素数打出来,就是2 ,3 ……31,然后开始dfs去跑这1 - n,如果不符合条件就回溯,这样会大大减少运算量。从最初的16!降低了多少我也说不清楚,反正1s就能把1 - 16的素数环跑完了,比16还小的n更加不在话下。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int prime[11] = {2,3,5,7,11,13,17,19,23,29,31};
int n, a[20];
bool vst[20];
bool Check_State(int x, int y)
{
int tmp = a[x - 1] + y;
int p = lower_bound(prime, prime + 11, tmp) - prime;
if(prime[p] == tmp)
return 1;
return 0;
}
void dfs(int x)
{
if(x == n)
{
if(Check_State(1, a[n - 1]))
{
for(int i = 0; i < n; i++)
printf("%d%c", a[i], i == n - 1 ? '\n' : ' ');
}
}
for(int i = 2; i <= n; i++)
{
if(!vst[i] && Check_State(x, i))
{
vst[i] = 1;
a[x] = i;
dfs(x + 1);
vst[i] = 0;
}
}
}
int main()
{
int k = 1;
while(scanf("%d", &n) != EOF)
{
if(k > 1)
printf("\n");
printf("Case %d:\n", k++);
memset(vst, 0, sizeof(vst));
a[0] = 1;
dfs(1);
}
return 0;
}