魔方阵

定义:

    n阶矩阵(n×n),满足每一行、每一列、对角线元素的和相同,n>=3

分类:

1、奇数阶魔方阵

2、双偶数阶魔方阵(4*k)

3、单偶数阶魔方阵(4*k+2)

1、奇数阶魔方阵

1)首行的中间赋值1,arr[0][n/2]=1

2)将2到n2依次赋值:整体规律是 行数减一,列数加一

3)特殊情况:行标i=0时,减一后赋值最后一行i=n-1;列标j=n-1时,加一赋值第一列j=0

4)特殊情况:原位置已被占用,则下一个数放在上一个数的下面

 

 1 void GetOddMagic(int arr[][MAX], int n)
 2 {
 3     int row = 0, col = n / 2, prow, pcol;
 4     arr[row][col] = 1;
 5     int t = 2;
 6     while (t <= n*n)
 7     {
 8         prow = row, pcol = col;//记录row,col的副本
 9         row = row>0 ? (--row) : (n - 1);//行数减一
10         col = col<(n - 1) ? (++col) : 0;//列数加一
11         if (arr[row][col])
12         {
13             row = prow, col = pcol;
14             arr[++row][col] = t;
15         }
16         else
17             arr[row][col] = t;
18         t++;
19     }
20 }
View Code

 2、双偶数阶魔方阵(4*k)

1)初始化为0矩阵,将矩阵看成4块

2)左上和右下1/4块:奇行偶列,偶行奇列的位置上赋值1;右上和左下1/4块:奇行奇列,偶行偶列的位置上赋值1

3)从左到右、上到下,遇到1则赋值,遇0不赋值。n*n->1

4)从左到右、上到下,遇到0则赋值,遇非零不赋值。1->n*n

  对于2):先实现左上部分块,然后反射给另外三面,左上->右上,上半->下半(小方阵的映像)

 1 void getDbEvenMatrix(int arr[][MAX],int n)
 2 {
 3     int i, j, k;
 4     for (i = 0; i < MAX; i++)
 5         for (j = 0; j < MAX; j++)
 6             arr[i][j] = 0;
 7     for (i = 0; i<n; i++)
 8         for (j = 0; j<n; j++)
 9         {
10             if (i<n / 2 && j<n / 2 || i >= n / 2 && j >= n / 2)
11                 if (i % 2 == 0 && j % 2 == 1 || i % 2 == 1 && j % 2 == 0)
12                     arr[i][j] = 1;
13             if (i >= n / 2 && j<n / 2 || i<n / 2 && j >= n / 2)
14                 if (i % 2 == 0 && j % 2 == 0 || i % 2 == 1 && j % 2 == 1)
15                     arr[i][j] = 1;
16         }
17     k = n*n;
18     for (i = 0; i<n; i++)
19         for (j = 0; j<n; j++)
20         {
21             if (arr[i][j])
22                 arr[i][j] = k;
23             k--;
24         }
25     k = 1;
26     for (i = 0; i<n; i++)
27         for (j = 0; j<n; j++)
28         {
29             if (!arr[i][j])
30                 arr[i][j] = k;
31             k++;
32         }
33     //输出双偶数魔方阵
34     for (i = 0; i<n; i++)
35     {
36         for (j = 0; j<n; j++)
37             cout << arr[i][j] << '	';
38         cout << endl;
39     }
40 }
View Code

3、单偶数魔方阵

1)分四块A,B,C,D,得到奇数魔方阵A,看做n/2阶方阵

2)A每个元素加(n/2)*(n/2)得到B;B每个元素加(n/2)*(n/2)得到C;C每个元素加(n/2)*(n/2)得到D

3)交换A和D中部分值:遍历A的行,遇到中间行,交换从中间列向右m列;非中间行,交换从第一列向右m列

4)交换C和D中部分值:遍历C的行,所有行,交换从中间列向左m-1列

 1 void getSgEvenMatrix(int arr[][MAX],int n)
 2 {
 3     int i, j, k;
 4     k = (n / 2)*(n / 2);
 5     for (i = 0; i < MAX; i++)
 6             for (j = 0; j < MAX; j++)
 7                 arr[i][j] = 0;
 8     getOddMagic(arr, n/2);
 9     //得到B,C,D 
10     for(i=0; i<n/2; i++)
11         for (j = 0; j < n / 2; j++)
12         {
13             arr[i + n / 2][j + n / 2] = arr[i][j] + k;
14             arr[i][j + n / 2] = arr[i][j] + 2 * k;
15             arr[i + n / 2][j] = arr[i][j] + 3 * k;
16         }
17     //A<->D,交换m列,按行分类
18     for(i=0; i<n/2; i++)
19     {
20         if(i == n/2/2)
21         {
22             for(j=i; j<n/2-1; j++)
23             {
24                 k = arr[i][j];//k已经无用 
25                 arr[i][j] = arr[i+n/2][j];
26                 arr[i+n/2][j] = k;
27             }
28         }
29         else
30         {
31             for(j=0; j<n/2/2; j++)
32             {
33                 k = arr[i][j];
34                 arr[i][j] = arr[i+n/2][j];
35                 arr[i+n/2][j] = k;
36             }
37         }
38     }
39     //C<->B,交换中间列向左m-1列 
40     for(i=0; i<n/2; i++)
41         for(j=0; j<(n/2-1)/2-1; j++)
42         {
43             k = arr[i][n/2+n/2/2-j];
44             arr[i][n/2+n/2/2-j] = arr[i+n/2][n/2+n/2/2-j];
45             arr[i+n/2][n/2+n/2/2-j] = k;
46         }
47     for (i = 0; i<n; i++)
48     {
49         for (j = 0; j<n; j++)
50             cout << arr[i][j] << '	';
51         cout << endl;
52     }
53 }
View Code
原文地址:https://www.cnblogs.com/guoyujiang/p/11795039.html