[蓝桥杯2015决赛]四阶幻方(DFS + 剪枝)

题目描述

把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时的所有方案数字


题解:

  1 #include 
  2 using namespace std;
  3 bool book[17];
  4 int ans;
  5 int average = 34;
  6 int mp[5][5];
  7 
  8 int jd(int i)
  9 {
 10 	int sum = 0;
 11 	sum = mp[i][0] + mp[i][1] + mp[i][2] + mp[i][3];
 12 	return sum;
 13 }
 14 bool judge(){
 15 	int sum;		//对角线 	
 16 	sum = mp[0][0] + mp[1][1] + mp[2][2] + mp[3][3];
 17 	if(sum != 34) return 0;
 18 	sum = mp[0][3] + mp[1][2] + mp[2][1] + mp[3][0];
 19 	if(sum != 34) return 0;
 20 	for(int i = 0; i < 4; ++ i)
 21 		if(jd(i) != average)
 22 		return 0;
 23 	for(int j = 0; j < 4; ++ j){
 24 		sum = mp[0][j] + mp[1][j] + mp[2][j]+ mp[3][j];
 25 		if(sum != 34)
 26 			return 0;
 27 	}
 28 	return 1;
 29 }
 30 void dfs(int n)
 31 {
 32 	if (n == 16){
 33 		if(judge())
 34 			ans++;
 35 		return ;
 36 	}
 37 	if (n % 4 == 0){//剪枝
 38 		if (jd(n/4 - 1) != average)
 39 			return;
 40 	}
 41 	for(int i = 2; i < 17; ++ i){
 42 		if(!book[i]){
 43 			book[i] = 1;
 44 			mp[n/4][n%4] = i;
 45 			dfs(n + 1);
 46 			book[i] = 0;
 47 		}
 48 	}
 49 }
 50 int main()
 51 {
 52 	mp[0][0] = 1;
 53 	dfs(1);
 54 	cout << ans << endl;
 55 }

你可能感兴趣的:([蓝桥杯2015决赛]四阶幻方(DFS + 剪枝))