幻方(Magic Square)1是一种将数字安排在正方形格子中,使每行、列和对角线上的数字和都相等的方法。 幻方有3种不同解法,分别对应于奇数阶, 4*m阶,以及4*m+2阶。 注:部分代码来源网络2
英姑对黄蓉说:“你算法自然精我百倍,可是我问你:将一至九这九个数字排成三列,不论纵横斜角,每三个字相加都是十五,如何排列?” 黄蓉当下低声诵道:“九宫之意,法以灵龟,二四为肩,六八为足,左三右七,戴九履一,五居中央。”边说边画,在沙上画了一个九宫之图。 ——金庸《射雕英雄传》第二十九回黑沼隐女 黄蓉给出的结果为: 4 9 2 3 5 7 8 1 6 更通用的解法如下: 1、把1填在第一行中央位置; 2、从2开始,每个数填在上一个数的左上角位置,越界则取模。 3、若左上角有数,则改填在上一个数的正下方。 上文中“左上角,正下方”可以改为其他对称情况,如黄蓉用的“右下角,正上方”。 代码如下:
void Magic_Odd(vector<vector<int> > &a){ int n = a.size(); int count = 2; int x = 0, y = n / 2; a[x][y] = 1; while (count <= n*n) { // get the new position int x2 = (x - 1 + n) % n; int y2 = (y - 1 + n) % n; if (a[x2][y2]) { x2 = (x + 1 + n) % n;// position is not valid, get next row. y2 = y; } x = x2; y = y2; a[x2][y2] = count++; }}黄蓉笑道:“不但九宫,即使四四图,五五图,以至百子图,亦不足为奇。“就说四四图罢,以十六字依次作四行排列,先以四角对换,一换十六,四换十三,后以内四角对换,六换十一,七换十。这般横直上下斜角相加,皆是三十四。 ——金庸《射雕英雄传》第二十九回黑沼隐女 通用的做法如下: 1、从数字1开始从小到大,即从左到右,从上到下进行填充; 2、将魔方中间n/2列的元素上、下进行翻转; 3、将魔方中间n/2行的元素左、右进行翻转。
这个就比较麻烦点了。需要将矩阵分块后一一解决。 1、将魔方分成A、B、C、D四个k阶方阵,如下图这四个方阵都为奇方阵,依次将A、D、B、C填充为奇魔方。 A B C D 2、交换A、C魔方元素: 对魔方的中间行,交换从中间列向右的m列各对应元素; 对其他行,交换从左向右m列各对应元素。 3、交换B、D魔方元素: 交换从中间列向左m – 1列各对应元素。
参考文献:
新闻热点
疑难解答