题目描述

从1~n(2<=n<=10)这n个数,摆成一个环, 要求相邻的两个数的和是素数, 按照由小到大请输出所有可能的摆放形式。

比如:n = 4,输出形式如下

1:1 2 3 4

2:1 4 3 2

3:2 1 4 3

4:2 3 4 1

5:3 2 1 4

6:3 4 1 2

7:4 1 2 3

8:4 3 2 1

total:8

比如:n = 6,输出形式如下

1:1 4 3 2 5 6

2:1 6 5 2 3 4

3:2 3 4 1 6 5

4:2 5 6 1 4 3

5:3 2 5 6 1 4

6:3 4 1 6 5 2

7:4 1 6 5 2 3

8:4 3 2 5 6 1

9:5 2 3 4 1 6

10:5 6 1 4 3 2

11:6 1 4 3 2 5

12:6 5 2 3 4 1

total:12

输入格式

一个整数n(2<=n<=10)

输出格式

前若干行,每行输出一个素数环的解,最后一行,输出解的总数

样例输入

4

样例输出

1:1 2 3 4

2:1 4 3 2

3:2 1 4 3

4:2 3 4 1

5:3 2 1 4

6:3 4 1 2

7:4 1 2 3

8:4 3 2 1

total:8

2 条评论

  • @ 2024-1-7 20:27:11

    image

    • @ 2024-1-7 20:23:51
      #include<iostream>
      #include<cstdio>
      #include<cmath>
      using namespace std;
      bool b[21]={0};//数组b[21]标志哪些数已经使用了 
      int total=0,a[21]={0};//a[21]相当于盒子 
      int search(int); //回溯过程
      int print(); //输出方案
      bool pd(int,int);  //判断素数
      int main()
      {
          search(1);//先站在1号小盒子面前 
          cout<<total<<endl; //输出总方案数
      }
      int search(int t)
      {
      	int i;
          for (i=1;i<=20;i++)  //有20个数可选
           	if (pd(a[t-1],i)&&(!b[i])) //判断与前一个数是否构成素数及该数是否可用
              {
      			a[t]=i;//数放在盒子 
      			b[i]=1;//标志已经用过 
      			if (t==20)//20个数已经放完 
      			{ 
      				if(pd(a[20],a[1])) print();//最后一个数如果和第一个数的和是素数,就打印出来 
      			} 
      			else 
      				search(t+1);//递归调用 
      			b[i]=0;//恢复标志位,以便下次调用 
              }
      }
      int print()
      {
      	total++;
      	printf("<%d>",total);
      	for (int j=1;j<=20;j++)
      		printf("%d ",a[j]);
      	printf("\n");
      }
      bool pd(int x,int y)
      {
          int k=2,i=x+y;
          while (k<=sqrt(i) && i%k!=0) k++;//如果一个数被2~自身的开方都不能相除,那它就是素数 
          if (k>sqrt(i)) return true;
          else return false;
      }
      
      
      
      • 1