4阶的话,可以考虑直接递归搜索。我试了试有2992组解。
1 2 11 12
4 9 8 5
7 10 3 14
6 13 16 15
1 2 11 12
4 9 8 5
13 10 3 14
6 7 16 15
1 2 11 12
4 15 8 5
7 16 3 14
6 13 10 9
1 2 11 12
4 15 8 5
13 16 3 14
6 7 10 9
1 2 11 12
10 3 8 5
7 16 15 14
6 13 4 9
1 2 11 12
10 3 8 5
13 16 15 14
6 7 4 9
1 2 11 12
10 9 8 5
7 4 3 14
6 13 16 15
1 2 11 12
10 9 8 5
7 4 15 14
6 13 16 3
1 2 11 12
10 9 8 5
13 4 3 14
6 7 16 15
1 2 11 12
10 9 8 5
13 4 15 14
6 7 16 3
…………
#include
#include
#include
#define MAX_NUM 30
#define _PRINT_ 0
unsigned long Result[MAX_NUM * MAX_NUM], ResultNum, Used[MAX_NUM * MAX_NUM]={0};
bool PrimeTable[MAX_NUM * MAX_NUM * 2]={ false };
unsigned long N, QN;
void CreatePrimeTable(void)
{
PrimeTable[0]=false;
PrimeTable[1]=false;
PrimeTable[2]=true;
PrimeTable[3]=true;
for(unsigned long j=5; j <= MAX_NUM * MAX_NUM * 2; j =2)
{
PrimeTable[j]=true;
for(unsigned long i=3; i <= sqrt((double)j); i =2)
{
if(j % i == 0)
{
PrimeTable[j]=false;
break;
}
}
}
}
inline bool IsPrime(unsigned long n)
{
return PrimeTable[n];
}
bool CheckIt(unsigned long Deep)
{
if(Deep == 0)
{
return true;
}
else if(Deep < N)
{
return IsPrime(Result[Deep] Result[Deep - 1]);
}
else if(Deep % N == 0)
{
return IsPrime(Result[Deep] Result[Deep - N]);
}
else
{
return(IsPrime(Result[Deep] Result[Deep - 1]) && IsPrime(Result[Deep] Result[Deep - N]));
}
}
void go(unsigned long Deep)
{
if(Deep == QN)
{
ResultNum ;
#if (_PRINT_)
printf("Find it! No。
%lu
", ResultNum);
for(unsigned long i=0; i < QN; i )
{
printf("%lu", Result[i]);
if(i % N == N - 1)
{
printf("
");
}
}
#else
printf("
Find:%lu", ResultNum);
#endif
}
else
{
for(unsigned long i=1; i <= QN; i)
{
if(!Used[i])
{
Result[Deep]=i;
if(CheckIt(Deep))
{
Used[i]=1;
go(Deep 1);
Used[i]=0;
}
}
}
}
}
int main()
{
DWORD tim;
ResultNum=0;
printf("Input N:");
scanf("%lu", &N);
QN=N * N;
tim=GetTickCount();
CreatePrimeTable();
go(0);
printf("
N=%lu
", N);
printf("Total=%lu
", ResultNum);
printf("Time=%lu
", GetTickCount() - tim);
return 0;
}
关于补充问题:
相邻 不包含斜方向的吧?相邻不就是上下、左右……包含斜线的话,再增加一种情况就可以了。
不过用的时间会多点。
全部