描述
有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。
为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。
-
输入
- 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。 输出
-
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
-
6 8 3 0
样例输出
-
Case 1: 1 4 3 2 5 6 1 6 5 2 3 4 Case 2: 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 Case 3:
No Answer
-
-
01.
#include <stdio.h>
02.
#include <string.h>
03.
#include <math.h>
04.
int
vis[22];
05.
int
a[22];
06.
int
n;
07.
int
isp(
int
x)
08.
{
09.
int
i;
10.
for
(i=2;i<=
sqrt
(x);i++)
11.
{
12.
if
(x%i==0)
//判断是否是素数
13.
{
14.
return
0;
15.
}
16.
}
17.
return
1;
18.
}
19.
void
dfs(
int
cur)
//深搜
20.
{
21.
int
f = 0;
22.
if
(f==1)
23.
{
24.
return
;
25.
}
26.
if
(cur==n && isp(a[0]+a[n-1]))
//判断深搜是否到底和首尾相加是否是素数 若是 则输出素数环
27.
{
28.
for
(
int
i=0;i<n;i++)
29.
{
30.
printf
(
"%d "
,a[i]);
//输出素数环的元素
31.
}
32.
printf
(
"\n"
);
33.
f = 1;
//深搜结束的条件
34.
return
;
35.
}
36.
else
37.
{
38.
for
(
int
i=2;i<=n;i++)
39.
{
40.
if
(!vis[i])
//即若 vis[i]==0
41.
{
42.
a[cur] = i;
//a[] 依次读取 2~n 之间(包括2和n)的数 能构成素数环的数 保留 否则将除去
43.
vis[i] = 1;
//初始化结束的条件 在满足要求后使循环能跳出
44.
if
(isp(a[cur]+a[cur-1]))
45.
{
46.
dfs(cur+1);
//深搜开始
47.
}
48.
vis[i]=0;
49.
}
50.
}
51.
}
52.
}
53.
int
main()
54.
{
55.
int
cou=1;
56.
a[0]=1;
//用来储存能构成素数环的元素
57.
vis[0]=1;
58.
while
(
scanf
(
"%d"
,&n)&&n)
59.
{
60.
memset
(vis,0,
sizeof
(vis));
//将vis[]清零
61.
printf
(
"Case %d:\n"
,cou++);
62.
if
(n==1)
//n==1时自环
63.
{
64.
printf
(
"1\n"
);
65.
}
66.
else
if
(n%2!=0)
/* 1~n组成一个素数环,相邻两个数的和为素数。首先偶数(2例外,但是本题不会出现两个数的和为2)不是素数,素数环里奇偶间隔 如果n是奇数 必定有两个奇数相邻的情况
67.
*/
{
68.
printf
(
"No Answer\n"
);
69.
}
70.
else
71.
{
72.
dfs(1);
//从1开始深搜
73.
}
74.
}
75.
return
0;
76.
}
-
-
-
-
上面是找的别人的代码
,
-
然后后来又自己写了个代码。只是将素数环里的数放到了一个数a里,所以它只能计算出n<10的素数环......
-
但是比较容易理解,仅供参考吧。
-
-
-
-
01.
#include <iostream>
02.
#include <algorithm>
03.
#include <cstdio>
04.
#include <bits/stdc++.h>
05.
using
namespace
std;
06.
int
c[100];
07.
int
q=0;
08.
int
prime(
int
n)
09.
{
10.
int
k=1;
11.
if
(n==3||n==2)
return
k;
12.
for
(
int
i=2; i*i<=n; i++)
13.
{
14.
if
(n%i==0)
15.
k=0;
16.
}
17.
return
k;
18.
}
19.
void
dfs(
int
n,
int
i,
int
a,
int
t) //n是输入给的n,i表示要放进去的数,a用来记录所有已放进去的数,t记录层数
20.
{
21.
a=a*10+i;
22.
//cout<<t<<" "<<a<<endl;
23.
if
(t==n-1) //一组数据已经搜到了底
24.
{
25.
26.
if
(prime(i+1))
27.
{
28.
q=1;
29.
cout<<a<<endl;
30.
}
31.
32.
}
33.
34.
for
(
int
j=2; j<=n; j++)
35.
{
36.
if
(c[j]==0)
37.
{
38.
if
(prime(j+i)) //如果第i个数加上第i+1个数是素数,就把第i+1个数放进去。否则,判断i+(i+2)是否为素数
39.
{
40.
c[j]=1;
41.
dfs(n,j,a,t+1);
42.
c[j]=0;
43.
}
44.
else
continue
;
45.
}
46.
}
47.
//return 0;
48.
}
49.
50.
int
main()
51.
{
52.
int
n,a;
53.
a=1; //这里的a和dfs里的a不是一个a
54.
while
(cin>>n)
55.
{
56.
57.
q=0;
58.
memset
(c,0,
sizeof
(c));
59.
if
(n==0)
break
;
60.
else
61.
{
62.
cout<<
"Case #"
<<a<<
": "
<<endl;
63.
dfs(n,1,0,0);
64.
}
65.
if
(q==0) cout<<
"No Answer"
<<endl;
66.
a++;
67.
}
68.
}