魔方阵,又叫幻方,在我国古代称为“纵横图”。由N^2个自然数构成的幻方叫N阶幻方,每行、每列及两对角线上各数之和都相等。魔方阵的求解要分三种情况讨论,N为奇数、N是偶数且是4的倍数,N是偶数但不是4的倍数。
一、N为奇数的情况
1、把1放在N*N方阵中的第一行中间一列。
2、后一个数存放的行数比前一个数存放的行数减1,若这个行数为0,则取行数为N;  
3、后一个数存放的列数比前一个数存放的列数加1,若这个列数为N+1,则取列数为1;  
4、如果前一个数是N的倍数,则后一个数存放的列数不变,而行数加1。 即放在前一个数的下面,也可以按照2、3算得的现在这个数位置上已经有数时直接把现在这个数放在它上一个数字的下面。
下图是N=3时候的步骤,依次从左到右,从上到下
魔方阵_职场
二、N为偶数且N为4的倍数的时候
先将1至N*N由小到大的顺序,从第一行开始依左上到右下的顺序填入N*N的方阵中,然后将N*N的方阵以4 行4列划分为若干个4*4的小方阵,再将所有4*4小方阵的两个对角线上的数字划掉,之后将所有被划掉的数字重新由大到小的进行排列(注意是所有的一起排列,不是每个4*4小阵内部排列),然后再将这些数字按排列顺序由N*N方阵 的第一行开始,放入被划掉的格子中去。
N=4的情况如下图,带颜色的是需要交换的数字,且相同的数字之间进行交换。
魔方阵_职场_02
也可以不用排序,但仍然是对角线上的数字需要变化,对于数字x,将其变为数字N*N+1-x。
例如上图中x=1时,将x变为4*4+1-1=16。
N=8的情况如下图
魔方阵_职场_03
三、N为偶数但不是4的倍数的情况 设N=4k+2
1、把方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。(注意不是ABCD的顺序)
魔方阵_休闲_04
2、在A象限的中间行、中间格开始,按自左向右的方向,标出k格。A象限的其它行则标出最左边的k格。将这些格,和C象限相对位置上的数,互换位置。
魔方阵_魔方阵_05魔方阵_魔方阵_06
3、在B象限任一行的中间格,自右向左,标出k-1列。(注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换), 将B象限标出的这些数,和D象限相对位置上的数进行交换,就形成幻方。
魔方阵_魔方阵_07
魔方阵_休闲_08
下面是6阶幻方的填法:6=4×1+2,这时k=1
 
魔方阵_职场_09
下面是我用C++编写的代码,只注重了方法,没重效率
魔方阵_休闲_10#include <iostream>
魔方阵_休闲_10using namespace std;
魔方阵_休闲_10void check(int **arr,int n)
魔方阵_休闲_10{
魔方阵_休闲_10  int r;
魔方阵_休闲_10        int c;
魔方阵_休闲_10        int sum[4]={0};
魔方阵_休闲_10    
魔方阵_休闲_10        for (r=0;r<n;r++)
魔方阵_休闲_10        {
魔方阵_休闲_10                sum[0]=0;
魔方阵_休闲_10                sum[1]=0;
魔方阵_休闲_10    
魔方阵_休闲_10                sum[2]+=arr[r][r];
魔方阵_休闲_10                sum[3]+=arr[n-r-1][r];
魔方阵_休闲_10    
魔方阵_休闲_10                for (c=0;c<n;c++)
魔方阵_休闲_10                {
魔方阵_休闲_10                        sum[0]+=arr[r][c];
魔方阵_休闲_10                        sum[1]+=arr[c][r];
魔方阵_休闲_10                }
魔方阵_休闲_10    cout<<"第"<<r+1<<"行:"<<sum[0]<<"\t第"<<r+1<<"列:"<<sum[1]<<endl;
魔方阵_休闲_10        }
魔方阵_休闲_10  cout<<"右 斜:"<<sum[2]<<"\t左 斜:"<<sum[3]<<endl;;
魔方阵_休闲_10    
魔方阵_休闲_10}
魔方阵_休闲_10void odd(int **cub,int n)
魔方阵_休闲_10{
魔方阵_休闲_10  cub[0][(n-1)/2]=1;
魔方阵_休闲_10  int prex=0;int prey=(n-1)/2;
魔方阵_休闲_10  for(int k=2;k<=n*n;k++)
魔方阵_休闲_10  {  int nowx,nowy;
魔方阵_休闲_10  if((k-1)%n==0)
魔方阵_休闲_10  {
魔方阵_休闲_10    nowx=prex+1;
魔方阵_休闲_10    nowy=prey;
魔方阵_休闲_10  }
魔方阵_休闲_10        
魔方阵_休闲_10  else
魔方阵_休闲_10  {
魔方阵_休闲_10    nowx=prex-1;
魔方阵_休闲_10    nowy=prey+1;
魔方阵_休闲_10    if(nowx<0)
魔方阵_休闲_10      nowx=n-1;
魔方阵_休闲_10    if(nowy>=n)
魔方阵_休闲_10      nowy=0;
魔方阵_休闲_10    
魔方阵_休闲_10  }
魔方阵_休闲_10  cub[nowx][nowy]=k;
魔方阵_休闲_10  prex=nowx;
魔方阵_休闲_10  prey=nowy;
魔方阵_休闲_10    
魔方阵_休闲_10    
魔方阵_休闲_10    
魔方阵_休闲_10    
魔方阵_休闲_10  }
魔方阵_休闲_10    
魔方阵_休闲_10}
魔方阵_休闲_10void main()
魔方阵_休闲_10{     int n;
魔方阵_休闲_10cout<<"请输入大于2的正整数n\n";
魔方阵_休闲_10cin>>n;
魔方阵_休闲_10int **cub=new int*[n];
魔方阵_休闲_10for(int i=0;i<n;i++)
魔方阵_休闲_10{
魔方阵_休闲_10  cub[i]=new int[n];
魔方阵_休闲_10  memset(cub[i],0,sizeof(int)*n);
魔方阵_休闲_10}
魔方阵_休闲_10if(n%2)//奇数
魔方阵_休闲_10{
魔方阵_休闲_10  odd(cub,n);
魔方阵_休闲_10    
魔方阵_休闲_10    
魔方阵_休闲_10}
魔方阵_休闲_10else if(n%4==0)//能被4整除的情况
魔方阵_休闲_10{
魔方阵_休闲_10  int temp[8]={0};
魔方阵_休闲_10  int cnt=1;
魔方阵_休闲_10  for(int i=0;i<n;i++)
魔方阵_休闲_10    for(int j=0;j<n;j++)
魔方阵_休闲_10    {
魔方阵_休闲_10      cub[i][j]=cnt;
魔方阵_休闲_10      cnt++;
魔方阵_休闲_10    }
魔方阵_休闲_10    
魔方阵_休闲_10    for(int p=0;p<=4*(n/4-1);p=p+4)
魔方阵_休闲_10      for(int q=0;q<=4*(n/4-1);q=q+4)
魔方阵_休闲_10      {    
魔方阵_休闲_10        for(int m=0;m<4;m++)
魔方阵_休闲_10        {
魔方阵_休闲_10          cub[m+p][m+q]=n*n+1-cub[m+p][m+q];
魔方阵_休闲_10          cub[m+p][3-m+q]=n*n+1-cub[m+p][3-m+q];
魔方阵_休闲_10        }
魔方阵_休闲_10        
魔方阵_休闲_10      }
魔方阵_休闲_10        
魔方阵_休闲_10}
魔方阵_休闲_10else    //不能被4整除的偶数
魔方阵_休闲_10{
魔方阵_休闲_10  int nn=n/2;
魔方阵_休闲_10  int k=n/4;
魔方阵_休闲_10  int **smallcub=new int *[nn];
魔方阵_休闲_10  for(int i=0;i<nn;i++)
魔方阵_休闲_10  {
魔方阵_休闲_10    smallcub[i]=new int[nn];
魔方阵_休闲_10    memset(smallcub[i],0,sizeof(int)*nn);
魔方阵_休闲_10  }
魔方阵_休闲_10  odd(smallcub,nn);
魔方阵_休闲_10  for(i=0;i<nn;i++)
魔方阵_休闲_10    for(int j=0;j<nn;j++)
魔方阵_休闲_10    {
魔方阵_休闲_10      cub[i][j]=smallcub[i][j];
魔方阵_休闲_10      cub[i+nn][j+nn]=smallcub[i][j]+nn*nn;
魔方阵_休闲_10      cub[i][j+nn]=smallcub[i][j]+2*nn*nn;
魔方阵_休闲_10      cub[i+nn][j]=smallcub[i][j]+3*nn*nn;
魔方阵_休闲_10    }
魔方阵_休闲_10    
魔方阵_休闲_10    int middle=(nn-1)/2;
魔方阵_休闲_10    for( i=0;i<nn;i++)
魔方阵_休闲_10      for(int j=0;j<k;j++)
魔方阵_休闲_10      {
魔方阵_休闲_10        if(i==middle)
魔方阵_休闲_10        {
魔方阵_休闲_10          int temp=cub[i][middle+j];
魔方阵_休闲_10          cub[i][middle+j]=cub[i+nn][middle+j];
魔方阵_休闲_10          cub[i+nn][middle+j]=temp;
魔方阵_休闲_10        }
魔方阵_休闲_10        else
魔方阵_休闲_10        {
魔方阵_休闲_10          int temp=cub[i][j];
魔方阵_休闲_10          cub[i][j]=cub[i+nn][j];
魔方阵_休闲_10          cub[i+nn][j]=temp;
魔方阵_休闲_10            
魔方阵_休闲_10        }
魔方阵_休闲_10        
魔方阵_休闲_10      }
魔方阵_休闲_10        
魔方阵_休闲_10      for(i=0;i<nn;i++)
魔方阵_休闲_10      {
魔方阵_休闲_10        for(int j=0;j<k-1;j++)
魔方阵_休闲_10        {
魔方阵_休闲_10            
魔方阵_休闲_10          int temp=cub[i][middle-j+nn];
魔方阵_休闲_10          cub[i][middle-j+nn]=cub[i+nn][middle-j+nn];
魔方阵_休闲_10          cub[i+nn][middle-j+nn]=temp;
魔方阵_休闲_10            
魔方阵_休闲_10        }
魔方阵_休闲_10      }
魔方阵_休闲_10        
魔方阵_休闲_10        
魔方阵_休闲_10        
魔方阵_休闲_10}
魔方阵_休闲_10for(i=0;i<n;i++)
魔方阵_休闲_10{  for(int j=0;j<n;j++)
魔方阵_休闲_10{
魔方阵_休闲_10  cout<<cub[i][j]<<"\t ";
魔方阵_休闲_10    
魔方阵_休闲_10}
魔方阵_休闲_10cout<<endl;
魔方阵_休闲_10}
魔方阵_休闲_10check(cub,n);
魔方阵_休闲_10
魔方阵_休闲_10}