蓝桥杯-四阶幻方

来源:互联网 发布:大作家智能写作软件 编辑:程序博客网 时间:2024/06/05 10:10

标题:四阶幻方

把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。
四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。

比如:

  12 15 16
  12 143 5
  13 710  4
  8 116 9

以及:
   1 12 13 8
  2 147 11
  15 310 6
  16 54 9

就可以算为两种不同的方案。

—————————————————————————————————————————————————————————————————————————————

/*==这里还是用了回溯法,回溯法最重要的是找到逻辑上的前进选择路线,含递归的性质。这里的选择是1——16的数字,每个节点逻辑上就是从这些数字来选择路线,比如1,后面选择2-15(到这是纯粹的回溯)。而这条路线受题目中的格子的 条件所约束,如每行=34,可以理解为递归了4层的和必须=34,这可以成为递归条件。 ==由于这里复杂度大,要根据这些条件进行剪枝,剪枝时,要找到当前尽可能多的条件,再来比较可能的限制。  如当前行的和>34,后面必定>34,所以不必再搜索,  if(current>34)return; //剪枝 if(j_temp==3&¤t+k!=34)continue;==还有要注意临界情况的处理,总之,回溯法对每一步骤要求清晰。 */ #include<iostream>using namespace std;int v[18];int a[4][4];__int64 ans;//judge,若不符合列,对角线条件return 0,否则return 1 int judge(){//列判断 for(int i=0;i<4;i++){int sum3=0;for(int j=0;j<4;j++){sum3+=a[j][i];}if(sum3!=34)return 0;}//对角线判断 int sum4=a[0][0]+a[1][1]+a[2][2]+a[3][3];if(sum4!=34)return 0;int sum5=a[0][3]+a[1][2]+a[2][1]+a[3][0];if(sum5!=34)return 0;return 1; }void dfs(int i,int j,int current){if(i==3&&j==3){ if(judge())ans++;return;}int i_temp,j_temp;//i_temp,j_temp为将要前进的格子的下标 if(j==3){i_temp=i+1;j_temp=0;}else if(j<3){i_temp=i;j_temp=j+1;}for(int k=2;k<=16;k++){//剪枝 if(current>34)return; if(j_temp==3&¤t+k!=34)continue;if(!v[k]){//若前面未使用过数字 k,则进行复制,递归 v[k]=1;a[i_temp][j_temp]=k;if(j_temp<3)dfs(i_temp,j_temp,k+current);elsedfs(i_temp,j_temp,0);//回溯时要特别注意还原一些变量。这里其实也可不执行a[i_temp][j_temp]=0; //因为current总是记录当前行能递归的格子的当前总值,一旦能递归,由a[i_temp][j_temp]=k;覆盖原值 a[i_temp][j_temp]=0; v[k]=0;}}}int main(){v[1]=1;a[0][0]=1;dfs(0,0,1);cout<<ans<<endl;return 0;} 
//答案为:416

==有疑问或建议,欢迎在下方留言评论^_^

0 0