题目描述
Apple最近迷上了做幻方,Apple还是个中高手,只要你说个奇数N就能把N*N的幻方做出来。其实你可以比他做得更好的。Apple总是画得很乱,而你可以利用程序排得很整齐^_^ 幻方的要求:每一行,每一列,还有两条斜线上数字的和都相等.输入格式
每行一个奇数N(0< N < 30),输入0结束输出格式
输入一个奇数,输出一个幻方,顺序参照样板输出;同一列的数右对齐,数与数用一个空格分开;输出完以后加一个回车。样例输入
5
1
0
样例输出
11 18 25 2 9
10 12 19 21 3
4 6 13 20 22
23 5 7 14 16
17 24 1 8 151
分析:
数字 1 放在最后一行的中间位置,然后按照如下规则填充其他数字:
- 向右下方移动一个位置,并依次填入数字,如果下一个位置已填有数字,就不往右下角走了,往上走一行
从数字1开始一直填充到n*n
- 如果超出矩阵的边界,则将位置移到对应的反方向位置(例如,超出上边界则移到下边界,超出右边界则移到左边界)。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while (true) {// 读取输入的奇数nint n = scanner.nextInt();if (n == 0) {break; // 如果输入为0,则退出循环} int[] format=new int[n];//每一列最长的数字位数,方便输出时右对齐int[][] magicSquare = generateMagicSquare(n,format);// 生成幻方矩阵// 输出幻方矩阵printMagicSquare(magicSquare,format);}}// 生成幻方矩阵的方法public static int[][] generateMagicSquare(int n,int[] format) {int[][] magicSquare = new int[n][n];int row = n - 1;//最下面一层的中间位置填1,也从此开始int col = n / 2;for (int num = 1; num <= n * n; num++) {//从数字1开始一直填充到n*nmagicSquare[row][col] = num;//填入数字// 计算每列最长数字的位数int digits = (int)(Math.log10(magicSquare[row][col]) + 1);format[col]=Math.max(format[col], digits);row = (row + 1) % n;//往右下方向移动到下一个位置,如果已经到达矩阵边界,则回到对应的行列的开头,%n是为了不超出n的范围col = (col + 1) % n;if (magicSquare[row][col] != 0) {//下一个位置已经填充了数字//下一个位置无法填充,返回原来的位置row = (row - 1 + n) % n;//将行向上移动一位col = (col - 1 + n) % n;//将列向左移动一位//来到原来位置的上一行row = (row - 1 + n) % n;}}return magicSquare;}// 输出幻方矩阵的方法public static void printMagicSquare(int[][] magicSquare, int[] format) {for (int i = 0; i < magicSquare.length; i++) {for (int j = 0; j < magicSquare[i].length; j++) {System.out.printf("%" + format[j] + "d ", magicSquare[i][j]); //每个数字占format[j]个格子}System.out.println(); // 换行}System.out.println(); // 输出空行}
}