A ring is composed of n (even number) circles as shown in diagram.
Put natural numbers 1, 2, . . . , n into each circle separately, and the
sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n ≤ 16)
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the
ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above
requirements.
You are to write a program that completes above process.
Sample Input
6
8
Sample Output
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
int ans[100]; //记录答案
void su ()
{
int i;
memset(a,0,sizeof(a));
for(i=2;i<100;i++){
if (a[i]==0){
int bei=2;
while((bei*i)<=100){
a[bei*i]=1;
bei++;
}
}
}
}
void node (int i)
{
ans[ji]=i;
mis[i]=0;
ji++;
// cout << i<< " " << endl;
if (ji==n)
if (!a[ans[ji-1]+ans[0]])
{
for (int ii=0;ii<n;ii++)
{
printf ("%d",ans[ii]);
if (ii==n-1) cout << endl;
else cout << " ";
}
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
else
{
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
for (int j=1;j<=n;j++)
{
if (mis[j]&&!a[j+i])
{
mis[j]=0;
node(j);
}
}
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
int main ()
{
freopen("in.txt","r",stdin);
int u=0;
su();
while (cin >> n)
{
if (u) cout << endl;
u++;
printf("Case %d:\n",u);
memset(ans,0,sizeof(ans));
ji=0;
for (int i=0;i<100;i++)
if (i>0&&i<=n) mis[i]=1;
else mis[i]=0;
mis[1]=0;
node(1);
}
return 0;
}
Put natural numbers 1, 2, . . . , n into each circle separately, and the
sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n ≤ 16)
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the
ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above
requirements.
You are to write a program that completes above process.
Sample Input
6
8
Sample Output
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
题意:输入正整数n,把1,2,3,……n组成一个环,使得相邻的两个整数之和均为素数。输出时从整数1开始逆时针排列,同一个换恰好输出一次。n<=16,首尾相领。
回溯思路:
1.判断这个数是否能用,能用就在答案里加上它,如果在当前情况下,这个数不能用了,就返回,关键:每次return前一定要回溯,即将标记为已使用的i重新改为未使用。
2.多组输出,一组答案(是否是答案判断条件为达到边界)成立就直接在函数里输出,不管这组答案是否成立,都要回溯,寻找下一组答案。
本题:
1.判断这个数能用条件:这个数没有用过,这个数和前一个数相加和为素数
2.答案成立条件,最后一个数和第一个数相加和为素数
3.回溯(设回溯数字为i)
(3)已用数字减少一个(ji--)
(1)从答案数组中除去(ans【ji】=0)
(2)将数字设为未使用(mis【i】=1)
4.判断达到边界ji==n
AC:
# include <iostream>
# include <cstdio>
# include <cstring>
# include <cmath>
using namespace std;
int n,ji; // ji为已经使用数字
int a[100]; //判断i是否为素数
int mis[100]; //判断i是否已使用int ans[100]; //记录答案
void su ()
{
int i;
memset(a,0,sizeof(a));
for(i=2;i<100;i++){
if (a[i]==0){
int bei=2;
while((bei*i)<=100){
a[bei*i]=1;
bei++;
}
}
}
}
void node (int i)
{
ans[ji]=i;
mis[i]=0;
ji++;
// cout << i<< " " << endl;
if (ji==n)
if (!a[ans[ji-1]+ans[0]])
{
for (int ii=0;ii<n;ii++)
{
printf ("%d",ans[ii]);
if (ii==n-1) cout << endl;
else cout << " ";
}
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
else
{
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
for (int j=1;j<=n;j++)
{
if (mis[j]&&!a[j+i])
{
mis[j]=0;
node(j);
}
}
ji--;
mis[i]=1;
ans[ji]=0;
return ;
}
int main ()
{
freopen("in.txt","r",stdin);
int u=0;
su();
while (cin >> n)
{
if (u) cout << endl;
u++;
printf("Case %d:\n",u);
memset(ans,0,sizeof(ans));
ji=0;
for (int i=0;i<100;i++)
if (i>0&&i<=n) mis[i]=1;
else mis[i]=0;
mis[1]=0;
node(1);
}
return 0;
}