幻方,有时又称魔方,由一组排放在正方形中的整数组成,其每行、每列以及两条对角线上的数之和均相等。通常幻方由从到的连续整数组成。
Siamese方法(Kraitchik 1942年,pp. 148-149)是构造奇数阶幻方的一种方法,说明如下:
1)把1放置在第一行的中间
2)从2开始直到n×n的各数依次放在右上方格中
3)当右上方格出界的时候,则由另一边则回绕。例如1在第1行,则2应放在最下一行,列数同样加1
4)如果按上面规则确定的位置上已有数,或上一个数位于最右上方时,则把下一个数放在上一个数的下面 按照以上步骤直到填写完所有方格。
输入: 自然数n(1<=n<=20,n是奇数) 输出: n行,每行n个数,每个数占4个字符位置。 提示:使用 printf("%4d", x) 来打印 思路分析
下面的程序使用 i 表示行,用 j 表示列, k 表示要放置的数,k 的范围是 [1..n*n]
放置的过程可以简要描述为:
1) 确定第0个数的位置
2) 放置 1~ n*n 个数:确定初步位置,也就是 i 和 j 的值; 如果出界,就进行调整;放置 k
3) 确定初步位置有两种选择:放置在前一个数的下方或者右上方
奇数魔方的自然语言描述如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 确定1的位置坐标 i 和 j; 在 i 和 j 这个位置放置 1; for (放置2~n*n个数) { if (k in [1,n+1,2*n+1, ..., (n-1)*n+1]) 下方; else { 右上方; } if (在第0行) 调整到第n行; if (在第n+1列) 调整到第1列; 放置 k 到 a[i][j]; } 输出二维矩阵; |
奇数魔方的C语言参考代码如下:
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 | #include <stdio.h> #define N 21 int main(int argc, char *argv[]) { int n, k, i, j; int a[N][N]; scanf("%d", &n); i= 1; j=(n+1)/2; a[i][j]=1; for (k=2; k<=n*n; k++) { if (k%n==1) i = i+1; else { i = i-1; j = j+1; } if (i==0) i = n; if (j==n+1) j = 1; a[i][j] = k; } for (i=1; i<=n; i++) { for (j=1; j<=n; j++) printf("%4d", a[i][j]); printf("\n"); } return 0; } |
奇数魔方的JAVA参考代码如下:
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 | import java.util.Scanner; public class P1304 { public static void main(String[] args) { Scanner cin = new Scanner(System.in); int n, k, i, j; n = cin.nextInt(); int [][] a = new int[n+1][n+1]; i= 0; j=(n+1)/2; for (k=1; k<=n*n; k++) { if (k%n==1 || n==1) i = i+1; else { i = i -1; j = j+1; } if (i==0) i = n; if (j==n+1) j = 1; a[i][j] = k; } for (i=1; i<=n; i++) { for (j=1; j<=n; j++) System.out.printf("%4d", a[i][j]); System.out.printf("\n"); } } } |