同心幻方

2024-01-21 22:01:31
标签: 幻方 同心幻方 镶边法 长蛇法 纵横图

轴心双对称型同心幻方镶边法构造方法及代码 

如果一个n阶的幻方,逐层地剥掉外圈,留下来的方阵仍然是一个个幻方,这个幻方就叫同心幻方,又叫嵌套幻方。

 上图中n=7,有3层幻方,最外层幻和为175,中间层和为125,内层和为75.

 如果幻方对角线两端的数之和,边上关于横向中间线轴对称的两数之和,关于纵向中间线轴对称的两数之和都相等,则称之为轴心双对称型幻方,这个和为n*n+1,其中一个数为另一个的补数。

 上图中n=8,对称两格有定和65,如6+59=7+58=1+64=9+56=18+47=23+42=15+50……=65,你找找看有哪些两数和为65.

 构选同心幻方,可以用镶边法。利用补数,从外到内先镶边后加入核心块,根据图示,分奇偶构造同心幻方。

一、奇阶同心幻方构造法 

 n=7为例,如图。先按序填写红色的数,每边上个数相同。然后根据互补两数和为50,填写黑色的数。比如1下方的为4910对角为40.

 再接着填写内层红色的数,与上步的顺序一致,但不是从1开始,而是接着上下步最大的红色的数。依次一直做到最内层为3阶为止。

 用罗伯法填写最内层3阶幻方。注意,它是边值也是关于中心对称的,不同于外层的关于轴对称。这样就完成了奇阶同心幻方的填写。

C++ 主要代码如下:

#include

int arr[20][20] = { 0 };

//构造奇数阶幻方的外边v为内层相对于最外层偏移量,s为开始值,q为相补两数之和

void odd(

const int nconst int vconst int sconst int q)

{

int k =

n / 2;

int val =

s;

arr[v][1 + v] = val;

arr[n - 1 +

v][1 + v] = q - val++;

 

int i = 0;

for (i = 0; i < k; i++)

{

arr[k + 1 + i + v][v] = val;

arr[k + 1 + i + v][n - 1 +

v] = q - val++;

}

for (i = 0; i < k - 1; i++)

{

arr[v][2 + i + v] = val;

arr[n - 1 +

v][2 + i + v] = q - val++;

}

for (i = 0; i < k; i++)

{

arr[1 + i + v][n - 1 +

v] = val;

arr[1 + i + v][v] = q - val++;

}

for (i = 0; i < k; i++)

{

arr[n - 1 +

v][n - 1 - i +

v] = val;

arr[v][n - 1 - i +

v] = q - val++;

}

arr[v][v] = q - arr[

n - 1 +

v][n - 1 +

v];//左上角

arr[v][n - 1 +

v] = q - arr[

n - 1 +

v][v];//改写右上角

}

 

void oddorder(

int n)

{

int k =

n / 2 - 1;

//层数

for (

int h = 0; h < k; h++)

{

odd(n - h * 2, h, 2 * h * (

n - h) + 1,

n *

n + 1);

}

lao_bo(3, k, (n *

n - 7) / 2);

//罗伯法

 

}

}

 n=11时的输出: 

 二、偶阶同心幻方构造法

1.双偶数阶幻方,以n=8为例:

  n=16时:

 2.单偶数阶幻方,以n=10为例:

 n=6时:

 这两种总是交替的,8阶是双偶,内层6阶就是单偶。核心处是4阶幻方,用对角线法填写。


 C++ 主要代码如下:

//单偶数阶镶边

void even1(

const int nconst int vconst int sconst int q)

{

int k =

n / 4;

int val =

s;

int i = 0;

for (i = 0; i < k; i++)

{

arr[v][2 + i * 4 + v] = val;

arr[n - 1 +

v][2 + i * 4 + v] = q - val++;

 

arr[v][3 + i * 4 + v] = val;

arr[n - 1 +

v][3 + i * 4 + v] = q - val++;

 

arr[n - 1 +

v][4 + i * 4 + v] = val;

arr[v][4 + i * 4 + v] = q - val++;

 

arr[n - 1 +

v][5 + i * 4 + v] = val;

arr[v][5 + i * 4 + v] = q - val++;

}

arr[v][v] = q - arr[

n - 1 +

v][n - 1 +

v];//左上角

arr[n - 1 +

v][v] = val;//左下角

arr[v][n - 1 +

v] = q - val++;

//右上角

 

for (i = 0; i < k; i++)

{

arr[1 + i * 4 + v][n - 1 +

v] = val;

arr[1 + i * 4 + v][v] = q - val++;

 

arr[2 + i * 4 + v][v] = val;

arr[2 + i * 4 + v][n - 1 +

v] = q - val++;

 

arr[3 + i * 4 + v][v] = val;

arr[3 + i * 4 + v][n - 1 +

v] = q - val++;

 

arr[4 + i * 4 + v][n - 1 +

v] = val;

arr[4 + i * 4 + v][v] = q - val++;

}

arr[v][1 + v] = val - 1;

arr[n - 1 +

v][1 + v] = q - (val - 1);

arr[n - 2 +

v][n - 1 +

v] = val;

arr[n - 2 +

v][v] = q - val;

}

//双偶数阶镶边

void even2(

const int nconst int vconst int sconst int q)

{

int k =

n / 4 - 1;

int val =

s;

int i = 0;

for (i = 0; i < k; i++)

{

arr[v][2 + i * 4 + v] = val;

arr[n - 1 +

v][2 + i * 4 + v] = q - val++;

 

 

arr[n - 1 +

v][3 + i * 4 + v] = val;

arr[v][3 + i * 4 + v] = q - val++;

 

arr[n - 1 +

v][4 + i * 4 + v] = val;

arr[v][4 + i * 4 + v] = q - val++;

 

arr[v][5 + i * 4 + v] = val;

arr[n - 1 +

v][5 + i * 4 + v] = q - val++;

}

arr[v][n - 2 +

v] = val;

arr[n - 1 +

v][n - 2 +

v] = q - val++;

 

arr[n - 1 +

v][n - 1 +

v] = val;//右下角

arr[v][v] = q - val++;

//左上角

 

arr[n - 1 +

v][v] = val;//左下角

arr[v][n - 1 +

v] = q - val++;

//右上角

 

arr[v][1 + v] = val;

arr[n - 1 +

v][1 + v] = q - val++;

 

for (i = 0; i < k; i++)

{

arr[1 + i * 4 + v][v] = val;

arr[1 + i * 4 + v][n - 1 +

v] = q - val++;

 

arr[2 + i * 4 + v][n - 1 +

v] = val;

arr[2 + i * 4 + v][v] = q - val++;

 

arr[3 + i * 4 + v][n - 1 +

v] = val;

arr[3 + i * 4 + v][v] = q - val++;

 

arr[4 + i * 4 + v][v] = val;

arr[4 + i * 4 + v][n - 1 +

v] = q - val++;

}

arr[n - 3 +

v][v] = val;

arr[n - 3 +

v][n - 1 +

v] = q - val++;

 

arr[n - 2 +

v][n - 1 +

v] = val;

arr[n - 2 +

v][v] = q - val++;

}

//构造偶数阶同心幻方

void evenorder(

int n)

{

int k =

n / 2 - 2;

//层数

for (

int h = 0; h < k; h++)

{

int nn =

n - h * 2;

if (nn % 4 == 0)even2(nn, h, 2 * h * (

n - h) + 1,

n *

n + 1);

else even1(nn, h, 2 * h * (

n - h) + 1,

n *

n + 1);

}

hai_er(4, k, (n *

n - 16) / 2);

//对角线法填写4阶幻方

}

 

N=20时的输出:

 

参考:

1. 最简奇阶幻方镶边法(再简化) - 知乎 (zhihu.com)

2. 构造镶边幻方的代码法 - 百度文库

 

阅读(0) 收藏(0) 转载(0) 举报/Report
相关阅读

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有