蓝桥杯-四阶幻方(DFS)

时间:2022-07-13 20:37:08
把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。

四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。
比如:
  1  2 15 16
 12 14  3  5
 13  7 10  4
  8 11  6  9

以及:
  1 12 13  8
  2 14  7 11
 15  3 10  6
 16  5  4  9
 
就可以算为两种不同的方案。

请提交左上角固定为1时的所有方案数字,不要填写任何多余内容或说明文字。


剪枝条件为:行、列、对角线的和是否为34。。。

但运行时间很长。。。。

#include<stdio.h>
#include<string.h>
int n;
int flag[16];
int map[4][4];
int sum=0;
int m=4;
int temp=34;
int check()
{
int num1,num2;
int i,j;
num1=num2=0;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
{
if(i==j) //判断正对角线
num1+=map[i][j];
}
if (num1!=temp)
return 0;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
{
if(i+j==(m-1)) //判断斜对角线
num2+=map[i][j];
}
if (num2!=temp)
return 0;
return 1;
}
int check1(int mark)
{ //判断行
int i;
int num=0;
for(i=0;i<m;i++)
{
num+=map[mark][i];
}
if(num!=temp)
return 0;
return 1;
}
int check2(int mark)
{ //判断列
int i;
int num=0;
for(i=0;i<m;i++)
{
num+=map[i][mark];
}
if(num!=temp)
return 0;
return 1;
}
void dfs(int count)
{
int i,j;
if(count%m==0 && count!=0)
{
if(!check1((count-1)/m))
return;
}
if(count==13 || count==14 || count==15 || count==16)
{
if(!check2((count-1)%m))
return;
}
if(count==m*m)
{
if(check())
{
sum++;
}
return;
}
for(i=0;i<m*m;i++)
{
if(!flag[i])
{
flag[i]=1;
map[count/m][count%m]=(i+1);
dfs(count+1);
flag[i]=0;
}
}
}
int main ()
{
memset(flag,0,16);
dfs(0);
printf ("%d\n",sum);
return 0;
}

输出结果为:7040;