原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1016
题目大意:
给你n个数。这些数为(1,2,3….n)。然后放入一个环中。要求每个数都要放入。同时每个数的左右两边的和都要为素数。输出所有的摆法
思路:
因为说给数字小于20,所以最大的素数为37
只需每次逐个深搜判断既可
Check数组用于临时存放顺序。只用满足的时候才会赋值给Keep
最后把Keep数组中的元素输出
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int CaseTime;//输出格式控制
int Number;
int DoneNumber;
int Ori[22]; //存放最初情况
int Check[22]; //存放这个数有没有被用过
int Keep[22];
//判断是否是素数
bool IsLeagal( int tmp )
{
if( tmp == 3 || tmp == 5 || tmp == 7 || tmp == 11 || tmp == 13 || tmp == 17 || tmp == 19 )
return true;
if( tmp == 23 || tmp == 31 || tmp == 37 )
return true;
return false;
}
void SetCircle( int Now_Number,int OverNumber ,int SetTime)
{
//放置完成后,输出放置结果。注意空格控制
if( OverNumber == Number )
{
int i;
for( i = 0; i < Number; i++ )
{
if( i != 0 ) cout<<" ";
cout<<Keep[i];
}
cout<<endl;
return;
}
int i;
for( i = 1; i <= Number ; i++ )
{
//判断是否放置到了最后一个。如果是还要比较和1求和的结果。
if( SetTime == Number-1 )
{
if( IsLeagal( Now_Number + Ori[i] ) && IsLeagal ( Ori[i] + 1 ) && !Check[i])
{
Check[i] = 1;
Keep[SetTime] = i;
SetCircle( i, OverNumber + 1, SetTime + 1 );
Check[i] = 0;
}
else
continue;
}
else
{
if( IsLeagal( Now_Number + Ori[i] ) && !Check[i])
{
Check[i] = 1;
Keep[SetTime] = i;
SetCircle( i, OverNumber + 1, SetTime + 1 );
Check[i] = 0;
}
else
continue;
}
}
}
int main()
{
int i;
for( i = 1; i <= 20; i++ )
Ori[i] = i;
CaseTime = 1;
while( cin >> Number )
{
memset( Check,0,sizeof( Check ));
Check[1] = 1;
Keep[0] = 1;
cout<<"Case "<<CaseTime<<":"<<endl;
SetCircle( 1,1 ,1);
cout<<endl;
CaseTime++;
}
return 0;
}