幻方,有时又称魔方,由一组排放在正方形中的整数组成,其每行、每列以及两条对角线上的数之和均相等。通常幻方由从到的连续整数组成。
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的位置坐标 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];
}
输出二维矩阵;
确定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语言参考代码如下:
#include
#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;
}
#include
#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参考代码如下:
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");
}
}
}
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");
}
}
}