1265: [蓝桥杯2015决赛]四阶幻方
题目链接: http://oj.ecustacm.cn/problem.php?id=1265
题目描述
把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,其他位置填数,每个数只能填一次,然后每行,每列,两条对角线的和都相等就算符合条件,求出一共有多少种符合条件的方案
思路:DFS再剪枝下,这题是填空题,最后直接输出即可
代码:
1 #pragma GCC optimize(2) 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<map> 8 #include<stack> 9 #include<set> 10 #include<vector> 11 #include<queue> 12 #include<iomanip> 13 using namespace std; 14 int a[5][5]; 15 int book[17]; 16 int sum=34; 17 int ans=0; 18 19 bool jd(int i) // 检查行 20 { 21 int num=0; 22 for(int j=0;j<4;j++) 23 num+=a[i][j]; 24 if(num!=sum) 25 return false; 26 return true; 27 } 28 29 bool check() // 核对是否满足要求 30 { 31 int num1=a[0][0]+a[1][1]+a[2][2]+a[3][3];// 主对角线 32 if(num1!=sum) 33 return false; 34 int num2=a[0][3]+a[1][2]+a[2][1]+a[3][0]; //副对角线 35 if(num2!=sum) 36 return false; 37 for(int i=0;i<4;i++) //行 38 { 39 if(!jd(i)) 40 return false; 41 } 42 for(int j=0;j<4;j++) // 列 43 { 44 int k=a[0][j]+a[1][j]+a[2][j]+a[3][j]; 45 if(k!=sum) 46 return false; 47 } 48 return true; 49 } 50 51 void dfs(int n) 52 { 53 if(n==16) 54 { 55 if(check()) 56 ans++; 57 return ; 58 } 59 if(n%4==0) // 剪枝下 60 { 61 if(!jd(n/4-1)) 62 return ; 63 } 64 for(int i=2;i<17;i++) //填充 65 { 66 if(!book[i]) 67 { 68 book[i]=1; 69 a[n/4][n%4]=i; 70 dfs(n+1); 71 book[i]=0; 72 } 73 } 74 } 75 76 int main() 77 { 78 a[0][0]=1; 79 dfs(1); 80 cout<<ans<<endl; 81 //cout<<416<<endl; //最后直接输出即可 82 return 0; 83 }
加油!
共同努力!
Keafmd