【问题描述】设计一个程序,使其将由1到N(N为偶数,且N <= 20)的N个正整数分别放置在由N个节点组成的环的各个节点上,其中1必须放在第一个节点上,并使任意两个相邻的节点上的数字之和为质数。

下图是当N为6时的一个例。当N为6时的输出样例如下:

1 4 3 2 5 6

1 6 5 2 3 4



【输入形式】程序从标准输入上读入一个偶数。

【输出形式】在标准输出上打印所有符合要求的排列方法。

输出有若干行,每一行都是符合题意的一种排列方法,所有数字从1所在位置开始,按顺时针方向依次输出,各个数字之间以空格分隔。

各行上的排列方式不重复。

注意:输出各行遵循“小数优先”原则, 在各种排列方式中,较小的数尽量靠前输出。如果将每行上的输出看成一个数字,则所有输出构成升序数列。具体格式见输出样例。

【样例输入】

8

【样例输出】

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

【样例说明】输入整数8,要求将1、2、……、8排成环且相邻两数之和为素数。

合法的排列方法共有4种,由运行结果可见,第2位上可能的数字只有2、4和6。且先输出2开头的所有合法排列,再输出4开头的所有合法排列,最后输出6开头的所有合法排列,余下部分同样遵循此原则。

【运行时限】要求每次运行时间限制在20秒之内。超出该时间则认为程序错误。

提示:当N增大时,运行时间将急剧增加。在编程时要注意尽量优化算法,提高运行效率。

【评分标准】该题要求输出若干行整数。如果你的程序计算的结果和标准答案完全一致,则该测试点得满分,否则该测试点得分为0。


#include<iostream>

#include <cmath>

using namespace std;

/*

* 《三金出品》

*

* 该题与树的结构类似,分支出多个情况==每个大槽位内部分有小槽位

*

*

*/

//  判断素数

bool isPrime(int value)

{

if (value == 1)

{

 return true;

}

for (int i = 2; i <= sqrt(value); i++)

{

 if (value%i == 0)

 {

  return false;

 }

}

return true;

}

void primecircle(int value,int n, int array_value [],int value_flag [])

{

//判断大槽位的个数是否满足条件,也就是n的值

//判断该数是否与1的和为素数&&判断该数组第一个元素是否为1

//以上两个条件满足打印数组

if (value == n +1&& isPrime(array_value[value-1]+array_value[1]) && array_value[1]==1)

{

 for (int i = 1; i <= n; i++)

 {

  cout << array_value[i] << " ";

 }

 cout << endl;

}

else

{ //把每个数试着存入value号的槽位

 for (int i = 1; i <= n; i++)

 {  //判断该数是否被使用过&&判断该数与之前的那个数是否和为素数

  if (value_flag[i] != 1 && isPrime(i + array_value[value-1]))

  {

   //存入槽位

   array_value[value] = i;

   value_flag[i] = 1;  //标记该数用过

   //下一个小槽位判断

   primecircle(value + 1,n,array_value,value_flag);

   //重新标记,置为0,便于其他大槽位使用

   value_flag[i] = 0;

  }

 }

}

}

int main()

{

int n;

cin >> n;      //个数的输入

int array_value[20] = {0};  //数据个数的存储

int value_flag[20] = {0};  //数据是否使用的标记

primecircle(1,n,array_value,value_flag);

}

——