先來科普一下什么叫n階幻方。
看過射雕英雄傳的人可能都記得,瑛姑閉關(guān)大半輩子,苦苦思索九宮格的問題,被黃蓉幾句口訣就破解了。瑛姑算的那個,就是3階幻方。
什么是幻方:
幻方(MagicSquare)是一種將數(shù)字安排在正方形格子中,使每行、列和對角線上的數(shù)字和都相等的方法。
行/列數(shù)為幾,就叫幾階幻方。
奇數(shù)幻方算法:
奇數(shù)幻方和偶數(shù)幻方的算法是完全不一樣的,所以我就分開來寫。本文講解奇數(shù)幻方。
其中最經(jīng)典的填法是羅伯法。先把1放在第一行正中;按以下規(guī)律排列剩下的(n×n-1)個數(shù),具體步驟為:
- 每一個數(shù)放在前一個數(shù)的右上一格;
- 如果這個數(shù)所要放的格已經(jīng)超出了頂行那么就把它放在底行,仍然要放在右一列;
- 如果這個數(shù)所要放的格已經(jīng)超出了最右列那么就把它放在最左列,仍然要放在上一行;
- 如果這個數(shù)所要放的格已經(jīng)超出了頂行且超出了最右列,那么就把它放在底行且最左列;
- 如果這個數(shù)所要放的格已經(jīng)有數(shù)填入,那么就把它放在前一個數(shù)的下一行同一列的格內(nèi)。
我大學(xué)專業(yè)課上講到幻方算法的時候,老師的比喻更貼切:把平面想像成一個球體,不斷地向右上繞著球體填數(shù),如果格子被占位,則向下一格重新開始繞圈,直至填滿。
大家可以想像一下,就象下圖這樣:
把紙卷成球,按箭頭方向繞圈填數(shù)
代碼:
理解了羅伯法以后,就可以用以下VBA來寫奇數(shù)幻方了:
Sub奇數(shù)幻方填寫_數(shù)組記錄()
n=Val(InputBox("請輸入[3-25]的奇數(shù):","n階幻方的階數(shù)",5))'階數(shù)輸入框,默認(rèn)輸入5
IfnMod2=0Orn<3Orn>25ThenMsgBox"階數(shù)不能為"&n:ExitSub'如果階數(shù)為偶數(shù),或超出定義范圍,則報錯并退出
[a1].CurrentRegion=""
[a1].Resize(n,n).Select
'清空并選擇填寫區(qū)域
ReDima(1Ton,1Ton)'定義數(shù)組
r=1:c=(n+1)/2'第一行中間填入1
a(r,c)=1
Fori=2Ton^2
Ifr=1Andc=nThen'到第1行最末一列時
r=r+1'去下一行
ElseIfr=1Then'第1行,非最末一列時
r=n:c=c+1'到最末第n行,列+1
ElseIfc=nThen'到最末第n列時
r=r-1:c=1'到第1列,行-1
ElseIfa(r-1,c+1)Then'右上格已填不為空時
r=r+1'去下一行
Else'其他
r=r-1:c=c+1'右上爬梯
EndIf
a(r,c)=i'順序填數(shù)
Next
Selection=a
EndSub
運行效果: