题目:http://acm.hdu.edu.cn/showproblem.php?pid=2183生成奇数魔方阵。
思路:
填魔术方阵的方法以奇数最为简单,第一个数字放在第一行第一列的正中央,
然后向右(左)上填,如果右(左)上已有数字,则向下填
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/**
 * Hdu 2183 奇数阶魔方(II)
 * <p>题目:<a href=http://acm.hdu.edu.cn/showproblem.php?pid=2183>
 * http://acm.hdu.edu.cn/showproblem.php?pid=2183</a></p>
 * @author ps
 */
public class Hdu2183 { /**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
while((str = br.readLine()) != null){
//当输入为0时退出。
if("0".equals(str)){
break;
}
int n = Integer.parseInt(str);

int[][] magic = magicOdd(n);
        for(int k = 0; k < magic.length; k++) {
            for(int l = 0; l < magic[0].length; l++) {
             int data = magic[k][l]; if (data >= 10) {
System.out.print("  "+data);
} else {
System.out.print("   " + data);
}
            }
            System.out.println();
         }
}
}
/**
 * 生成奇数魔方阵
 * <p>填魔术方阵的方法以奇数最为简单,第一个数字放在第一行第一列的正中央,
 * 然后向右(左)上填,如果右(左)上已有数字,则向下填</p>
 * @param n 某一奇数
 * @return 返回生成后的数据。
 */
public static int[][] magicOdd(int n) {
        int[][] square = new int[n+1][n+1];         int i = 0; 
        int j = (n+1) / 2;         for(int key = 1; key <= n*n; key++) { 
            if((key % n) == 1) 
                i++; 
            else { 
                i--; 
                j++; 
            }             if(i == 0) 
                i = n; 
            if(j > n) 
                j = 1;             square[i][j] = key; 
        }
        
        int[][] matrix = new int[n][n];
        
        for(int k = 0; k < matrix.length; k++) {
           for(int l = 0; l < matrix[0].length; l++) {
               matrix[k][l] = square[k+1][l+1];
           }
        }
        
        return matrix;
    }
}

解决方案 »

  1.   

    修改了一下main函数,主要是输出方面你肯定不符合题目要求,应该用printf的public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = null;
    while ((str = br.readLine()) != null) {
    int n = -1; try {
    n = Integer.parseInt(str);
    } catch (Exception e) { } // 当输入为0时退出。
    if (n == 0) {
    break;
    }
    if (n < 3 || n > 21 || n % 2 == 0) {
    System.out.println("illegal");
    continue;
    } int[][] magic = magicOdd(n);
    for (int k = 0; k < magic.length; k++) {
    for (int l = 0; l < magic[0].length; l++) {
    int data = magic[k][l];
    System.out.printf("%4d", data);
    }
    System.out.println();
    }
    }
    }
    另外你貌似也没有处理非法输入,题目要求是3-21的奇数,我这里对于不是整数、小于3、大于21的数以及偶数都输出illegal,对于0退出,我按照个人理解判断得更宽泛了一些,转换结果为0都退出
      

  2.   

    System.out.printf("%4d", data);ls的这句错啦
      

  3.   

    2楼的System.out.printf("%4d", data); 没有错呀。同时2楼的意见,我不太认同。虽然在平时编程时说是要这样做非法处理,
    但在ACM里面我觉得没有必要呀,因为它测试的是你的算法而已。
    只是还是WA而已。
      

  4.   

    我觉得不管什么时候,严谨都是必要的额……重写了生成数组算法,方法就是题目上面提到的先斜向全部写出,然后折叠import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;/**
     * Hdu 2183 奇数阶魔方(II)
     * <p>
     * 题目:<a href=http://acm.hdu.edu.cn/showproblem.php?pid=2183>
     * http://acm.hdu.edu.cn/showproblem.php?pid=2183</a>
     * </p>
     * 
     * @author ps
     */
    public class Hdu2183 { /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = null;
    while ((str = br.readLine()) != null) {
    int n = -1; try {
    n = Integer.parseInt(str);
    } catch (Exception e) { } // 当输入为0时退出。
    if (n == 0) {
    break;
    }
    if (n < 3 || n > 21 || n % 2 == 0) {
    System.out.println("illegal");
    continue;
    } int[][] magic = magicOdd(n);
    for (int k = 0; k < magic.length; k++) {
    for (int l = 0; l < magic[0].length; l++) {
    int data = magic[k][l];
    System.out.printf("%4d", data);
    }
    System.out.println();
    }
    }
    } /**
     * 生成奇数魔方阵
     * <p>
     * 填魔术方阵的方法以奇数最为简单,第一个数字放在第一行第一列的正中央, 然后向右(左)上填,如果右(左)上已有数字,则向下填
     * </p>
     * 
     * @param n
     *            某一奇数
     * @return 返回生成后的数据。
     */
    public static int[][] magicOdd(int n) {
    int[][] square = new int[2 * n - 1][2 * n - 1]; for (int i = 0, m = 1; i < n; i++)
    for (int j = 0; j < n; j++)
    square[i + j][n - 1 - i + j] = m++; for (int i = 0; i < 2 * n - 1; i++) {
    for (int j = 0; j < 2 * n - 1; j++) {
    if (square[i][j] != 0) {
    if (i < n / 2)
    square[i + n][j] = square[i][j];
    else if (i > 2 * n - 2 - n / 2)
    square[i - n][j] = square[i][j];
    else if (j < n / 2)
    square[i][j + n] = square[i][j];
    else if (j > 2 * n - 2 - n / 2)
    square[i][j - n] = square[i][j];
    }
    }
    } int[][] matrix = new int[n][n]; for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
    matrix[i][j] = square[i + n / 2][j + n / 2]; return matrix;
    }
    }
    如果觉得有些处理没必要自己去掉吧