由n階幻方問題引發的思考

由n階幻方問題想到的

前序

       最近在學習一些經典的算法,搞得頭昏腦漲,就想換換腦子。在家裏的舊書堆裏面亂翻,無意中將一本具有十多年曆史的小學數學奧林匹克競賽的書發掘了出來,能放到現在挺不容易的,就拿起來隨便翻翻。看了看目錄,一個個熟悉的問題又一次的展現在了我的面前,看着看着就翻到了n階幻方這塊(其實那時候我們不這麼叫)。記得當時學這個問題的時候就感覺特別有意思,現在看看也是如此,於是乎便誕生了本片文章。
       本文用較大的篇幅先介紹了n階幻方,因爲這個問題挺有意思。但是本文的重點卻在第二節---由n階幻方引發的思考。

目錄
        第一節 n階幻方問題
       第二節 由n階幻方引發的思考

正文

第一節 n階幻方問題

         所謂n階幻方問題,俗稱“橫豎斜相加和相等”(我們當時就是這麼叫的)。用術語說就是:在一個N行N列的方格表中,有1,2,3......N*N-1,N*N這N*N個整數,且其對角線、橫行、縱行的數字和都相等。
       好了,在具體詳解該問題之前,我們先看個例子,熟悉一下,如下圖所示:



由上圖可知,幻方有奇數階幻方和偶數階幻方兩種,而偶數階幻方又分爲4m階幻方和4m+2階幻方兩類。

1.奇數階幻方
       我記得基數階幻方有個口訣,有了這個口訣,走遍奇數幻方都不怕。其實這個口訣也是實現奇數幻方的步驟。


奇幻七絕
  先填上行正中央,
  依次斜填切莫忘。
  上格沒有頂格填,
  頂格沒有底格放。

我作圖解釋一下這首七絕。

       看着圖是不是有點亂,具體每一步我就不做圖說明了,你自己可以看着口訣寫一下,挺有意思。要是感覺3*3方格寫起來沒有意思,你可以試一下5*5,7*7或者更大的。寫完了之後看看橫豎斜相加和是否相等。
附註:如果上述口訣有什麼問題,請留言說明,謝謝!

ok,奇數幻方就講完了,就這麼簡單。權當找樂子!


2.偶數階幻方
       說實話,偶數階幻方我一直以爲只有一種,就是2*n階幻方問題。查了一下才知道偶數階幻方也分爲兩小類。

 ①.4*n階幻方
       4*n階幻方的生成其實很簡單,即對方格中對角線上的數據,先以一條對角線(稱對角線一)爲對稱軸,交換另一對角線(稱對角線二)的數據;然後以對角線二爲對稱軸,交換對角線一的數據。說的直白一點,假設矩陣名爲MagicSquare,就是交換MagicSquare[i,j]和MagicSquare[n-1-i,n-1-j]。老辦法,作圖來說明。圖如下:



好了,4*n階幻方也晚了,怎麼樣,簡單吧!自己動手試試吧。

  ②.4*n+2階幻方
        4*n+2,乍一看就較4*n麻煩了,事實也是如此,不過它的思想也簡單。就是將4*n+2看做2*(2*n+1),這樣一來就轉化成了四個2*n+1求幻方。
附註:下面的我以6階幻方爲例,那麼,4*n+2=6,所以n=1。

我通過描述每個步驟加上圖形的方式來表述4*n+2階幻方實現的過程。

第一步:把整個表格分成4個(2*n+1)*(2*n+1)的小表格,分別叫A,B,C,D。見下圖

第二步:這樣A,B,C,D個小表格就成奇數幻方問題了。
       ①.將1,2,...,(2*n+1)*(2*n+1)這些數劃分給A,並對A實現奇數幻方;
       ②.將(2*n+1)*(2*n+1)+1,...,2*(2*n+1)*(2*n+1)這些數劃分給B,並對B實現奇數幻方;
       ③.將2*(2*n+1)*(2*n+1)+1,...3*(2*n+1)*(2*n+1)這些數劃分C,並對C實現奇數幻方;
       ④.將3*(2*n+1)*(2*n+1)+1,...4*(2*n+1)*(2*n+1)這些數劃分D,並對D實現奇數幻方。
見下圖

第三步:從A表中的中心(即第n行的MagicSquare[n][n])開始,按照從左向右的方向,標出n個數,A表中的其他行則標出最左邊的n格中的數(在圖中用紅色背景標出)。並且將這些標出的數和C表中的對應位置互換。見下圖

第四步:在B表中的中心(如上解釋)開始,自右向左,標出n-1列,將B中標出的數據與D表中對應位置的數據交換。但是6階幻方中,n-1此時等於0,所以B與D不用做交換。


至此,這個幻方就成了,如下圖。

附註:以上幾個問題的程序就不送上了,有興趣的朋友可以自己寫一下。

 

第二節 由n階幻方想到的

       幻方問題就說完了,比較一下我還是感覺奇數階幻方有意思,而且比偶數階幻方問題容易些,沒有那麼麻煩。按說寫到此本應該結束了,可是我突發奇想,n階幻方這個問題利用數學知識很容就能解決,那麼我想問一下大家:在平時寫程序思考算法的時候,你是否會利用數學知識來解決問題呢?

       假如這個問題讓你在限定的時間內編程來實現.如果你對n階幻方很瞭解,知道奇偶兩種情況的做法,好,那沒有問題,恭喜你!但是,恰巧你對n階幻方不是很瞭解,也不知道奇偶階幻方的做法,那這個問題你會怎麼解決?用枚舉還是用其他什麼算法。這是你不得不考慮的。

       說到這,我又想到了一個例子,如:求1,2,...,99,100的和,請編程實現。你會怎麼做?這個確實很簡單,我相信多數朋友都會用一個for或是一個while來解決問題。那還有沒有更簡單的辦法呢?當然有,利用數學知識來解決,1,2,...,99,100就是一個等差數列,等差數列求和的公式S=(首項+末項)*項數/2,直接得出結果。哪個效率更高,不言而喻。所以說,數學知識在我們編程中很有用,只是我們經常考慮不到而已!

 

第三節 結束語

         如果你有更有趣或者值得深思的題目請分享!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章