Prime Ring Problem(素数环)
题目描述:
余队长某天ak太多了心烦,想带领他的队员做游戏 。
游戏内容如下:
当余队长喊出一个数字n时,便有n个队员,身上带着1到n的数字,手牵手拉成一个环。当环里的每个人相邻两人身上数字之和都为素数时,便找到了一个环。当找出所有的环时,游戏便结束。
Note: 每个环的第一个数字必须是1
Input
n (0 < n < 20).
Output
输出格式如下方输出样例所示。
每行一串数字表示一种环中数字的排列顺序。数字的顺序必须满足:从1开始,顺时针或逆时针。按字典序输出所有解决方案。您将编写一个完成上述过程,帮助大家顺利完成游戏的程序。
别忘了在每组方案后面输出一个空行。
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
思路:
运用回溯和递归的思想
AC代码:
#include<stdio.h>
#include<math.h>
bool b[1010]; //定义一个数组用来存是否为素数,1为素数,0为合数(不是素数),因为bool只有0和1所以定义bool,当然int型也可以,记得数组开大点,要不然会超限
int ii;
int total;
int a[101];
//定义判断函数
//pd就是判断的意思,定位bool型和数组b的原因一样
bool pd(int x,int y) //判断是否为素数
{
int k,e;
e=x+y; //用e表示两个数相加,因为是两个数相加判断是否为素数
for(k=2;k<=sqrt(e);k++)
{
if(e%k==0)
{
return 0; //表示不是素数
}
}
return 1; //没有一个数可以整除,表示为素数,返回1
}
//定义打印函数
int print()
{
total++;
for(int j=1;j<=ii;j++)
{
if(a[1]==1&&j!=ii)
{
printf("%d ",a[j]); //每个数要用空格隔开,但最后一个数直接换行,用一个if判断就行了。
} //如果不这样会格式错误
else if(a[1]==1&&j==ii)
{
printf("%d",a[j]);
}
else return 0; //不retur会打印空行
}
printf("\n");
//return 0;
//因为定义的是int,所以要有返回值,但是对答案不影响,不打retur 0,答案不会错所以我注释掉了。
}
//递归
int search(int t)
{
for(int i=1;i<=ii;i++)
{
if(pd(a[t-1],i)&&(!b[i]))
{
a[t]=i;
b[i]=1;
if(t==ii)
{
if(pd(a[ii],a[1]))print(); //判断+打印
}
else search(t+1); //递归
b[i]=0; //把bool b从新赋值为0,这里是回溯的思想
}
}
// return 0;
//和上面的print函数的 retur 0原因一样。
}
int main()
{
int c=1; //定义一个计数器,输出的时候让输出Case n:。
while(~scanf("%d",&ii)) //多组输入
{
printf("Case %d:\n",c);
search(1); //调用search函数
printf("\n"); //题目要求每组后面多一个换行
c++; //每次输入完后计数器加一
}
return 0;
}
注:用C语言提交要把bool型改成int型要不然会报语法错误,我错了好几次。