1. 程式人生 > >【ZZULIOJ】1203: 做幻方

【ZZULIOJ】1203: 做幻方

題目

1203: 做幻方

​ Time Limit: 1 Sec Memory Limit: 128 MB Submit: 388 Solved: 89
(https://acm.zzuli.edu.cn/zzuliacm/bbs.php?pid=1203)

Description

Apple最近迷上了做幻方,Apple還是個中高手,只要你說個奇數N就能把N*N的幻方做出來。其實你可以比他做得更好的。Apple總是畫得很亂,而你可以利用程式排得很整齊^_^ 幻方的要求:每一行,每一列,還有兩條斜線上數字的和都相等.

Input

每行一個奇數N(0< N < 30),輸入0結束

Output

輸入一個奇數,輸出一個幻方,順序參照樣板輸出;同一列的數右對齊,數與數用一個空格分開;輸出完以後加一個回車。

Sample Input

510

Sample Output

11 18 25 2 9

10 12 19 21 3

4 6 13 20 22

23 5 7 14 16

17 24 1 8 15

1

HINT

Source

思路

​ N 為奇數時,最簡單:

⑴ 將1放在第一行中間一列;

⑵ 從2開始直到n×n止各數依次按下列規則存放:

按 45°方向行走,如向右上

每一個數存放的行比前一個數的行數減1,列數加1

⑶ 如果行列範圍超出矩陣範圍,則迴繞。

例如1在第1行,則2應放在最下一行,列數同樣加1;

⑷ 如果按上面規則確定的位置上已有數,或上一個數是第1行第n列時,

則把下一個數放在上一個數的下面。

例如:3階的幻方

8 1 6

3 5 7

4 9 2

1.確定1的位置 累加1;

2.優先將值賦給自己右上角的位置(n為階數-1)

特殊:如果右上角行下標<0 則賦值給同列最下面的位置

特殊:如果右上角列下表>n 則賦值給同行最左邊的位置

3.如果上述位置被佔領,則賦值給自己下面(行數不變列數+1;

程式碼

#include<stdio.h>
#include<math.h> #define N 30 int sqr(int m); int main() { int m; while(scanf("%d", &m), m != 0) { sqr(m); } return 0; } int sqr(int m) { int a[N][N] = {0}; int x=0, y=0; int times, p, q, fmt; int i, j; x = m / 2; y = m - 1; times = m * m; for(i = 0 ; i < times ; i++) { a[y][x] = i + 1; p = x; q = y; x = x + 1; if(x == m) x = 0; y = y + 1; if(y == m) y = 0; if(a[y][x] != 0) { x = p; y = q - 1; } } fmt = log10(times); if(fmt == 0) { for(i = 0 ; i < m ; i++) { for(j = 0 ; j < m - 1 ; j++) { printf("%d ", a[i][j]); } printf("%d", a[i][m - 1]); printf("\n"); } } else if(fmt == 1) { for(i = 0 ; i < m ; i++) { for(j = 0 ; j < m - 1 ; j++) { printf("%2d ", a[i][j]); } printf("%2d", a[i][m - 1]); printf("\n"); } } else if(fmt == 2) { for(i = 0 ; i < m ; i++) { for(j = 0 ; j < m - 1; j++) { printf("%3d ", a[i][j]); } printf("%3d", a[i][m - 1]); printf("\n"); } } printf("\n"); return 0; }

U