奇數階幻方的演算法
Ⅰ c ++奇數階幻方
因為你是通過用戶輸入的方式確定幻方的階數,而定義二維數組的維數必須是一個常數,不能是n這個變數,要麼你就在程序中規定二維數組的大小,這個可以用宏定義規定n大小,#define n x,x是一個確定的常數
第二種方法是將數組變成二維動態數組如下所示
int **p;
p=new int*[n];
for(int i=0;i<n;i++){
p[i]=new int*[n];
}
我是用手機打的字,格式不是很標准,具體你可以網路一個二維動態數組,這個知識點應該是在你們後面才會學,現在應該還沒學
Ⅱ 對於一個n為奇數的n*n縱橫圖(幻方)的C++程序
n階幻方的填法(n≥3) 收藏
幻方,亦稱縱橫圖。台灣稱為魔術方陣。將自然數1,2,3,……n*n排列成一個n*n方陣,使得每行、每列以及兩對角線上的各個數之和都相等,等於n/2*(n*n+1),這樣的方陣稱為幻方。
例如:把1,2,3,4,5,6,7,8,9填入3*3的格子,使得:每行、每列、兩條對角線的和是15。
8 1 6
3 5 7
4 9 2
n是它的階數,比如上面的幻方是3階。n/2*(n*n+1)為幻方的變幻常數。數學上已經證明,對於n>2,n階幻方都存在。
目前填寫幻方的方法,是把幻方分成了三類,每類又有各種各樣的填寫方法。這里對於這三類幻方,僅舉出一種方便手工填寫的方法。
1、奇數階幻方
n為奇數 (n=3,5,7,9,11……) (n=2*k+1,k=1,2,3,4,5……)
奇數階幻方最經典的填法是羅伯特法(也有人稱之為樓梯方)。填寫方法是這樣:
把1(或最小的數)放在第一行正中; 按以下規律排列剩下的n*n-1個數:
(1)、每一個數放在前一個數的右上一格;
(2)、如果這個數所要放的格已經超出了頂行那麼就把它放在底行,仍然要放在右一列;
(3)、如果這個數所要放的格已經超出了最右列那麼就把它放在最左列,仍然要放在上一行;
(4)、如果這個數所要放的格已經超出了頂行且超出了最右列,那麼就把它放在前一個數的下一行同一列的格內;
(5)、如果這個數所要放的格已經有數填入,處理方法同(4)。
這種寫法總是先向「右上」的方向,象是在爬樓梯。
2、雙偶階幻方
n為偶數,且能被4整除 (n=4,8,12,16,20……) (n=4k,k=1,2,3,4,5……)
先說明一個定義:
互補:如果兩個數字的和,等於幻方最大數和最小數的和,即 n*n+1,稱為互補。
先看看4階幻方的填法:將數字從左到右、從上到下按順序填寫:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
這個方陣的對角線,已經用藍色標出。將對角線上的數字,換成與它互補的數字。
這里,n*n+1 = 4*4+1 = 17;
把1換成17-1 = 16;把6換成17-6 = 11;把11換成17-11 = 6……換完後就是一個四階幻方。
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
對於n=4k階幻方,我們先把數字按順序填寫。寫好後,按4*4把它劃分成k*k個方陣。因為n是4的倍數,一定能用4*4的小方陣分割。然後把每個小方陣的對角線,象製作4階幻方的方法一樣,對角線上的數字換成互補的數字,就構成幻方。 下面是8階幻方的作法:
(1) 先把數字按順序填。然後,按4*4把它分割成2*2個小方陣
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
(2) 每個小方陣對角線上的數字,換成和它互補的數。
64 2 3 61 60 6 7 57
9 55 54 12 13 51 50 16
17 47 46 20 21 43 42 24
40 26 27 37 36 30 31 33
32 34 35 29 28 38 39 25
41 23 22 44 45 19 18 48
49 15 14 52 53 11 10 56
8 58 59 5 4 62 63 1
3、單偶階幻方
n為偶數,且不能被4整除 (n=6,10,14,18,22……) (n=4k+2,k=1,2,3,4,5……)
這是三種裡面最復雜的幻方。
以n=10為例。這時,k=2
(1) 把方陣分為A,B,C,D四個象限,這樣每一個象限肯定是奇數階。用樓梯法,依次在A象限,D象限,B象限,C象限按奇數階幻方的填法填數。
A B
C D
17 24 1 8 15 67 74 51 58 65
23 5 7 14 16 73 55 57 64 66
4 6 13 20 22 54 56 63 70 72
10 12 19 21 3 60 62 69 71 53
11 18 25 2 9 61 68 75 52 59
92 99 76 83 90 42 49 26 33 40
98 80 82 89 91 48 30 32 39 41
79 81 88 95 97 29 31 38 45 47
85 87 94 96 78 35 37 44 46 28
86 93 100 77 84 36 43 50 27 34
(2) 在A象限的中間行、中間格開始,按自左向右的方向,標出k格。A象限的其它行則標出最左邊的k格。
>>>
17 24 1 8 15 67 74 51 58 65
23 5 7 14 16 73 55 57 64 66
4 6 13 20 22 54 56 63 70 72
10 12 19 21 3 60 62 69 71 53
11 18 25 2 9 61 68 75 52 59
92 99 76 83 90 42 49 26 33 40
98 80 82 89 91 48 30 32 39 41
79 81 88 95 97 29 31 38 45 47
85 87 94 96 78 35 37 44 46 28
86 93 100 77 84 36 43 50 27 34
(3) 將這些格,和C象限相對位置上的數,互換位置。
92 99 1 8 15 67 74 51 58 65
98 80 7 14 16 73 55 57 64 66
4 6 88 95 22 54 56 63 70 72
85 87 19 21 3 60 62 69 71 53
86 93 25 2 9 61 68 75 52 59
17 24 76 83 90 42 49 26 33 40
23 5 82 89 91 48 30 32 39 41
79 81 13 20 97 29 31 38 45 47
10 12 94 96 78 35 37 44 46 28
11 18 100 77 84 36 43 50 27 34
(4) 在B象限任一行的中間格,自右向左,標出k-1列。(註:6階幻方由於k-1=0所以不用再作B、D象限的數據交換)
<<<
92 99 1 8 15 67 74 51 58 65
98 80 7 14 16 73 55 57 64 66
4 6 88 95 22 54 56 63 70 72
85 87 19 21 3 60 62 69 71 53
86 93 25 2 9 61 68 75 52 59
17 24 76 83 90 42 49 26 33 40
23 5 82 89 91 48 30 32 39 41
79 81 13 20 97 29 31 38 45 47
10 12 94 96 78 35 37 44 46 28
11 18 100 77 84 36 43 50 27 34
(5) 將B象限標出的這些數,和D象限相對位置上的數進行交換,即可完成。
92 99 1 8 15 67 74 26 58 65
98 80 7 14 16 73 55 32 64 66
4 6 88 95 22 54 56 38 70 72
85 87 19 21 3 60 62 44 71 53
86 93 25 2 9 61 68 50 52 59
17 24 76 83 90 42 49 51 33 40
23 5 82 89 91 48 30 57 39 41
79 81 13 20 97 29 31 63 45 47
10 12 94 96 78 35 37 69 46 28
11 18 100 77 84 36 43 75 27 34