标题:四阶幻方
把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时的所有方案数字,不要填写任何多余内容或说明文字。
思路:本来我是全排列15个数,结果时间太长,因为是每次排列完16个数之后,才进行判断
需要在dfs的时候就先判断前四个,前八个,前16个,这样时间上会省很多时间
下面是代码,结果是416,本来我的结果是7040,因为我排列的时候是从1 到 16 进行全排列的,所以错了,
如果答案是7040的都是从1开始dfs的,
正确答案是416,得从2开始dfs
本人能力有限,目前只有能力这么写,
下面是代码
#include<stdio.h>
int count = 0,k = 0;
int b[20] = {1};
int a[20] = {0};
int swap(int a[],int i,int j)
{
int t;
t = a[i];
a[i] = a[j];
a[j] = t;
}
int f1()
{
if(b[12]+b[13]+b[14]+b[15] != 34)return 0;
if(b[0]+b[4]+b[8]+b[12] != 34)return 0;
if(b[1]+b[5]+b[9]+b[13] != 34)return 0;
if(b[2]+b[6]+b[10]+b[14] != 34)return 0;
if(b[3]+b[7]+b[11]+b[15] != 34)return 0;
if(b[0]+b[5]+b[10]+b[15] != 34)return 0;
if(b[3]+b[6]+b[9]+b[12] != 34)return 0;
return 1;
}
int f(int n)
{
int i;
if(n == 4)
{
if(b[0]+b[1]+b[2]+b[3] != 34)return 0;
}
else if(n == 8)
{
if(b[4]+b[5]+b[6]+b[7] != 34)return 0;
}
else if(n == 12)
{
if(b[8]+b[9]+b[10]+b[11] != 34)return 0;
}
if(n == 16)
{
if(f1() == 1){
printf("\n第%d个",++count);
for(i = 0; i < 16; i++)
{
if(i % 4 == 0)printf("\n");
printf("%3d",b[i]);
}
printf("\n");
}
}
for(i = 2; i < 17; i++)
{
if(a[i] == 0)
{
a[i] = 1;
b[n] = i;
f(n+1);
a[i] = 0;
}
}
}
int main()
{
f(1);
printf("\n%d",count);
}