这题我用的是DFS。不多说,看代码和注释。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
//因为n<20,所以最大的素数也就是40左右,因此用一个数组来记录45以内的素数,用于之后的判定。
bool isprime[45]={0,1,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0};
int n;
bool visited[24];//用于标记是否被访问过
void dfs(int cnt,int id,int ans[])
{
if(cnt==n+1)
{
printf("%d",ans[1]);
for(int i=2;i<=n;i++)
printf(" %d",ans[i]);
printf("\n");
return;
}
for(int i=2;i<=n;i++)
{
if(visited[i]||i==id)
continue;
visited[i]=true;
if(cnt==n)//这里注意要区分是不是到达第n个数,如果到达因为是圆环,所以还要判定和1相加是不是素数。
{
int t1=ans[cnt-1]+i;
int t2=i+1;
if(isprime[t1]&&isprime[t2])
{
ans[cnt]=i;
dfs(cnt+1,i,ans);
}
}
else//否则就判断和前一个数相加是不是素数
{
int t=ans[cnt-1]+i;
if(isprime[t])
{
ans[cnt]=i;
dfs(cnt+1,i,ans);
}
}
visited[i]=false;//记得恢复
}
}
int main()
{
int k=1;
while(scanf("%d",&n)!=EOF)
{
int ans[25];
ans[1]=1;
memset(visited,false,sizeof(visited));
visited[1]=true;
printf("Case %d:\n",k++);
dfs(2,1,ans);
printf("\n");
}
return 0;
}