當初小學時,我非常地癡迷奧數。在我記憶裏邊,我遇到得最早,最讓我癡迷的,幻方絕對是排在了前三位。
還記得那是四年級(哈哈,這個年齡真不算早,但那種對於奧數的感情,絕對是最純真的熱愛)我接觸到神奇的幻方,然後自己鼓搗,找到了幻方的規律,就是這篇博客所用到的。所以,當我整理自己的舊書時,看到幻方,腦子一熱,說幹就幹。
首先是幻方的起源,一段非常奇妙的故事。大約兩千多年前西漢時代,流傳夏禹治水時,黃河中躍出一匹神馬,馬背上馱着一幅圖,人稱「河圖」;又洛水河中浮出一隻神龜,龜背上有一張象徵吉祥的圖案稱爲「洛書」。“河出圖,洛出書,聖人則之。”
說到這裏,我又想起來了華爲的“河圖”,每個時代都會需要一些創作來證明它的存在,只不過,創作的人不一樣罷了。
幻方,雖然發現規律的過程可能對於一個小學生而言並不順利,但是拿着規律去產出幻方對於任何人來說都不困難。
算法思想:
- 從第一行的最中心開始填1,依次向右上移動填寫下一個數。
- 如果從上方超出,則移動到最下面一格填寫;
- 如果從右方超出,則移動到最左邊一格填寫;
- 如果右上方有數,或是右上頂角,則移動到相對下方的一格填寫;
(抱歉,現在我沒學會用電腦畫幻方方格圖)
三階幻方填寫的實現:
#include<iostream>
using namespace std;
int main()
{
int num[3][3] = { 0 };
int m = 0;
int n = 1;
num[0][1] = 1;
for (int i = 2; i <= 9; i++)
{
m--;
n++;
if (m == -1&&n!=3)//判上出界
{
m = m + 3;
num[m][n] = i;
}
else if(n==3&&m!=-1)//判右出界
{
n = n - 3;
num[m][n] = i;
}
else if (num[m][n] != 0)//判右上有數
{
m = m + 2;
n = n - 1;
num[m][n] = i;
}
else if (m == -1 && n == 3)//判右上頂角
{
m = m + 2;
n = n - 1;
num[m][n] = i;
}
else//通性右上填寫
{
num[m][n] = i;
}
}
for (m = 0; m <= 2; m++)
{
for (n = 0; n <= 2; n++)
{
cout << num[m][n] << "\t";
}
cout << endl;
}
}
奇數階幻方(通式)實現:
#include<iostream>
using namespace std;
int main()
{
int k;
cout << "你希望得到的幻方階數是(<=99):" << endl;
cin >> k;
int num[99][99] = { 0 };
int m = 0;
int n = (k-1)/2;
num[0][(k-1)/2] = 1;
for (int i = 2; i <= k*k; i++)
{
m--;
n++;
if (m == -1 && n != k)//判上
{
m = m + k;
num[m][n] = i;
}
else if (n == k && m != -1)//判右
{
n = n - k;
num[m][n] = i;
}
else if (m == -1 && n == k)//判右上頂角
{
m = m + 2;
n = n - 1;
num[m][n] = i;
}
else if (num[m][n] != 0)//判右上有數
{
m = m + 2;
n = n - 1;
num[m][n] = i;
}
else//通性右上
{
num[m][n] = i;
}
}
for (m = 0; m <k; m++)//輸出
{
for (n = 0; n <k; n++)
{
cout << num[m][n] << "\t";
}
cout << endl;
}
}