题目描述
把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. c/c++
#include <bits/stdc++.h>
using namespace std;
int vis[17];
int m[5][5];
int cnt = 0;
bool judge()
{
for (int i = 0; i < 4; i ++ ) { //四行四列的和
if (m[i][0] + m[i][1] + m[i][2] + m[i][3] != 34) return 0;
if (m[0][i] + m[1][i] + m[2][i] + m[3][i] != 34) return 0;
}
if (m[0][0] + m[1][1] + m[2][2] + m[3][3] != 34) return 0;//对角线
if (m[0][3] + m[1][2] + m[2][1] + m[3][0] != 34) return 0;
return 1;
}
void dfs(int n)
{
if (n == 16)
{
if (judge()) cnt ++;
return;
}
if (n%4 == 0) //简单剪枝:检查第一行的和是不是34
if (m[n/4 - 1][0] + m[n/4 - 1][1] + m[n/4 - 1][2] + m[n/4 - 1][3] != 34)
return;
for (int i = 2; i <= 16; i ++ )
{
if (vis[i] == 0) {
m[n/4][n%4] = i;
vis[i] = 1;
dfs(n + 1);
vis[i] = 0;
}
}
}
int main()
{
m[0][0] = 1;
dfs(1);
cout << cnt << endl; //416
return 0;
}