魔方阵:一个N阶魔方阵即N行N列的数组,其每一行的和==每一列的和==对角线的和。
例如一个3阶魔方阵:
8 1 6
3 5 7
4 9 2
一:3阶魔方阵
这里我们用两种方法实现:
方法一:遍历三阶数组的所有条件,将符合条件的(行的和==列的和==对角线和)挑出来。这种方法可以打印出多种情况。
方法二:
1.将1放在第一行的中间
2.后面的数字放在当前数字的的上一行后一列
3.如果当前位置有数据,就放在前一个数字的下一行同列
方法一代码:
bool TiaoJian_1(int arr[3][3])//魔方阵的条件:9个数字互不相等
{
if(arr[0][0] != arr[1][0] && arr[0][0] != arr[1][2] && arr[0][1]!= arr[1][1] &&
arr[0][0] != arr[0][1] && arr[0][1] != arr[0][2] && arr[0][2] != arr[1][0]&&
arr[1][0] != arr[1][1] && arr[1][1] != arr[1][2] && arr[1][2] != arr[2][0]&&
arr[2][0] != arr[2][1] && arr[2][1] != arr[2][2] && arr[1][0]!= arr[2][0])
{
return true;
}
else
{
return false;
}
}
bool Tiaojian_2(int h[3],int l[3],int dj[2])
{
if(h[0]==h[1] && h[1]==h[2] && h[2]==l[0] &&
l[0]==l[1] && l[1]==l[2] && l[2]==dj[0] &&dj[0]==dj[1])
{
return true;
}
else
{
return false;
}
}
int MagicCube_3()
{
int arr[3][3];
int h[3];
int l[3];
int dj[2];
int n = 10;
for(int i1 = 1;i1<n;i1++)//给3*3个元素分别赋值1~10,共9^9种情况;一个for循环一个元素,共9个
{
arr[0][0] = i1;
for(int i2 = 1;i2<n;i2++)
{
arr[0][1] = i2;
for(int i3 = 1;i3<n;i3++)
{
arr[0][2] = i3;
for(int j1 = 1;j1<n;j1++)
{
arr[1][0] = j1;
for(int j2 = 1;j2<n;j2++)
{
arr[1][1] = j2;
for(int j3 = 1;j3<n;j3++)
{
arr[1][2] = j3;
for(int k1 = 1;k1<n;k1++)
{
arr[2][0] = k1;
for(int k2 = 1;k2<n;k2++)
{
arr[2][1] = k2;
for(int k3 = 1;k3<n;k3++)
{
arr[2][2] = k3;
if(TiaoJian_1( arr ))
{
for(int i = 0;i <= 3;i++)//h[0] h[1] h[2]
{
h[i] = arr[i][0]+arr[i][1]+arr[i][2];
l[i] = arr[0][i]+arr[1][i]+arr[2][i];
}
dj[0] = arr[0][0]+arr[1][1]+arr[2][2];
dj[1] = arr[0][2]+arr[1][1]+arr[2][0];
if(Tiaojian_2(h,l,dj))
{
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
printf("\n\n");
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
这个方法的时间复杂度太大,代码也没有优化,把所有情况打印完毕计算机要运行5分钟左右。第一次体会到跑代码的快感。
方法二代码如下:
void Magic_teacher_3()
{
#define ROW 3
#define COL 3
int arr[ROW][COL] = {0};//将arr全部元素置零
int row = 0;
int col = COL/2;
arr[row][col] = 1;//将1放在第一行的中间
for(int i = 2;i <= ROW*COL;i++)//2.后面的数字放在当前数字的的上一行后一列
//3.如果当前位置有数据,就放在前一个数字的下一行同列
{
row--;//上一行
if(row < 0)//如果行为负数,把行置为最后一行
{
row += ROW;
}
col++;//下一列
if(col > COL-1)//如果列大于最高列,把col置为第一列
{
col = COL - col;
}
if(arr[row][col] != 0)//如果当前位置有数据,放到前一数字的下一行同列
{
row = (row + 2) % ROW;
col = (col-1+COL) %COL;
}
arr[row][col] = i;
}
for(int i= 0;i < ROW;i++)//打印魔方阵
{
for(int j = 0;j < COL;j++)
{
printf("%-3d",arr[i][j]);
}
printf("\n");
}
}
二:4阶魔方阵(同8阶算法类似)
这里也用两种方法实现。
方法一:
void MagicCube_4()//4阶魔方阵
{
#define N 4
int arr[N ][N ];
int m = 1;
for(int i = 0;i < N;i++)
{
for(int j = 0;j < 4;j++)
{
arr[i][j] = m++;
}
}
int Firstnum = arr[N-1][N-1];
//主对角线清零
for(int i= 0;i <N;i++)
{
for( int j = 0 ;j<N;j++)
{
if(i == j)
{
arr[i][j] = 0;
}
}
}
//副对角线清零
for(int i = 0;i < N;i++)
{
for(int j = 0;j < N;j++)
{
if((i+j) == 3)
{
arr[i][j] = 0;
}
}
}
//对角线填数字 firstnum = 16;第一个数字为16
for(int i = 0;i<N;i++)
{
for(int j = 0;j<N;j++)
{
if(arr[i][j] == 0)
{
arr[i][j] = Firstnum --;
}
else
{
Firstnum--;
}
}
}
//打印结果
for(int i = 0;i< N;i++)
{
for(int j = 0;j<N;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
方法二:
这里的从右上至左下应该为: ((i+j)%4)!=3
代码如下:
void Magic_8()//8阶或者4阶魔方阵
{
#define ROW 8
int arr[ROW][ROW];
int tmp = 1;
int tmp2 = ROW*ROW;
for(int i=0;i<ROW;i++)
{
for(int j=0;j<ROW;j++)
{
if((i%4!=j%4) && ((i+j)%4!=3))
{
arr[i][j] = tmp;
}
else
{
arr[i][j] = tmp2;
}
tmp++;
tmp2--;
}
}
for(int i=0;i<ROW;i++)
{
for(int j=0;j<ROW;j++)
{
printf("%-4d",arr[i][j]);
}
printf("\n");
}
/*if(!Check(arr,ROW))//准备写一个检查函数,检查每行每列对角线的和是否相等。(待更新)
{
printf("不是魔方阵\n");
}*/
}