直接上T:
很显然,题目已经指明了模拟方向,于是我就暴力模拟AC通过了;下面是代码:
package P2615;
import java.util.*;
public class Main {
public static void main(String[] args) {
//录入数据
Scanner in = new Scanner(System.in);
int N = in.nextInt();
//创建幻方
int arr[][] = new int[N][N];
arr[0][N/2]=1;//放1
//创建flag1和flag2分别记录K-1是否是第一行,是否是zuihou一列;再记录行和列分别的数值
int flag_hang = 1;int hang = 0;
int flag_lie = 0;int lie = N/2;
//从2....直到N*N
for(int i=2;i<=N*N;i ++) {
if(flag_hang == 1 && flag_lie == 0) {
arr[N-1][lie+1] = i;
//flag_change
flag_hang = 0;
if(++lie == N-1) flag_lie = 1;
else flag_lie = 0;
//hang\lie_change
hang = N-1;
}else if(flag_hang == 0 && flag_lie == 1) {
arr[hang-1][0] = i;
//flag_change
flag_lie = 0;
if(--hang == 0) flag_hang = 1;
else flag_hang = 0;
//hang\lie_change
lie = 0;
}else if(flag_hang == 1 && flag_lie == 1) {
arr[1][N-1] = i;
flag_hang = 0;flag_lie = 1;
hang = 1;lie = N-1;
}else if(flag_hang == 0 && flag_lie == 0) {
if(arr[hang-1][lie+1] == 0) {
arr[hang-1][lie+1] = i;
if(--hang == 0)flag_hang = 1;
if(++lie == N-1)flag_lie = 1;
}
else {
arr[hang+1][lie] = i;
hang ++;
}
}
}
for(int i = 0;i <= N-1;i++) {
for(int j = 0;j < N-1;j ++)
System.out.printf(arr[i][j]+" ");
System.out.print(arr[i][N-1]);
System.out.printf("\n");
}
}
}
但这不是重点!!!
神奇的幻方必然有它的神奇之处;在生成完整幻方的过程中,并不是有四个上面的if情况,阅读完大佬的解析后,发现它的神奇之处在于:可以用一个规律生成整个幻方,而不是4个;步骤如下:
先在第一行中间填入1;
检查上一个填入元素的右上角是否有元素
1)如果已经有元素,则填到该元素下方
2)如果没有,则填入该元素右上角的位置
循环填入元素直到填满
注意
这里的右上角,并不只是狭义的,而是可以“取模”的;上栗子:
这里的2就是1的“右上角”;
既然算法已经明确,就不上代码了||