打印以下程序

求个程序,打印出以下数据:

1   2   6   7  15  16  28  29  45 

3   5   8  14  17  27  30  44  46 

4   9  13  18  26  31  43  47  60 

10  12  19  25  32  42  48  59  61 

11  20  24  33  41  49  58  62  71 

21  23  34  40  50  57  63  70  72 

22  35  39  51  56  64  69  73  78 

36  38  52  55  65  68  74  77  79 

37  53  54  66  67  75  76  80  81 

跟楼上几位思路差不多~
发现我的变量命名真是烂啊

[code="java"]
public class pbox {
public static void main(String[] args) {
printBox(9);
}

public static void printBox(int row) {
    if (row < 1) {
        System.out.println("......");
        return;
    } else if (row > 80) {
        System.out.println("......");
        return;
    }
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < row; j++) {
            int s = i + j;
            int sm = s > row - 1 ? s - (row - 1) : 0;
            int s1 = sumOfAS(1, s, 1);
            int s2 = sumOfAS(2, sm - 1, 2);
            int sf = s1 - s2;
            int x = s % 2 == 0 ? j - sm : i - sm;
            int oyeah = x + sf + 1;
            System.out.printf("%3d", oyeah);
        }
        System.out.println();
    }

}

// 等差数列求和
public static int sumOfAS(int o, int n, int j) {
    return o * n + (n - 1) * n * j / 2;
}

}
[/code]

:x

[code="java"]package test;

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    for (int x = 1; x < 10; x++) {
        for (int y = 1; y < 10; y++) {
            if ((x + y) <= 10) {
                int lineNum = x + y - 1;

                int topOfLast = (lineNum - 1) * (lineNum) / 2;

                // if direction is true,up
                // otherwise, down
                boolean direction = lineNum % 2 != 0 ? true : false;

                if (direction) {
                    System.out.print("" + (topOfLast + y) + "  ");
                } else {
                    System.out.print("" + (topOfLast + lineNum - y + 1)
                            + "  ");
                }
            } else {
                /*int innerX = x;
                int innerY = y;
                int offsetX = 8;
                int offsetY = 1;

                innerX -= offsetX;
                innerY -= offsetY;

                int lineNum = innerX + innerY - 1;

                int loopNum = 0;
                int start = 8;
                for (int j = 1; j < lineNum; j++) {
                    loopNum += start;
                    start--;
                }
                System.out.println("loopNum:" + loopNum);
                int topOfLast = loopNum + 45;
                ;

                // if direction is true,up
                // otherwise, down
                boolean direction = lineNum % 2 != 0 ? false : true;

                if (direction) {
                    System.out.println("dddd" + (topOfLast + innerY - 1) );
                    System.out.print("" + (topOfLast + innerY - 1) + "  ");
                } else {
                    System.out.print("" + (topOfLast + lineNum - innerY + 1)
                            + "  ");
                }

*/
}
}
System.out.println();
}

}

}[/code]

明天再继续,
暂时只能打一边,
右边应该一样的

已经做出来了.. 其实前半程的很简单, 难的是后半程的, 而且, SIZE不一样, 后半程的判断逻辑也有不一样. [一直被卡在这个地方. 耗了很多时间.]
[code="java"] 1 2 6 7 15 16 28 29 45
3 5 8 14 17 27 30 44 46
4 9 13 18 26 31 43 47 60
10 12 19 25 32 42 48 59 61
11 20 24 33 41 49 58 62 71
21 23 34 40 50 57 63 70 72
22 35 39 51 56 64 69 73 78
36 38 52 55 65 68 74 77 79
37 53 54 66 67 75 76 80 81[/code]

[code="java"]package cn.iwoo;

public class PrintTest {
/**
* 需要打印的数组的长度
*/
public static int SIZE = 9;

public static void main(String[] args) {
    int[][] all = new int[SIZE][SIZE];

    // 初始位置
    int x = 0;
    int y = 0;
    all[x][y] = 1;

    Direction lastDirection = Direction.H; // 上一次走的方向 

    for (int i = 1; i < SIZE * SIZE; i++) {
        Direction position = getNextDirection(lastDirection, x, y); // 得到要走的方向
        lastDirection = position;

        int[] nextLocation = getNextLocation(position, x, y); // 得到要走的坐标
        x = nextLocation[0];
        y = nextLocation[1];

        all[x][y] = i + 1; // 给坐标赋值
    }

    // 打印
    printArray(all);
}

/**
 * <p>
 * Description: 打印数组
 * </p>
 */
private static void printArray(int[][] array) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (j == 0) {
                System.out.println("");
            }
            System.out.print(" " + array[j][i]);
        }
    }
}

/**
 * <p>
 * Description: 得到下一个坐标
 * </p>
 * @param position 要走的方向
 * @param x
 * @param y
 * @return
 */
private static int[] getNextLocation(Direction position, int x, int y) {
    int[] nextLocation = new int[2];

    if (Direction.H.equals(position)) {
        nextLocation[0] = x + 1; // 水平走, x + 1, y不变
        nextLocation[1] = y;

    } else if (Direction.V.equals(position)) {
        nextLocation[0] = x; // 垂直走, x, y + 1
        nextLocation[1] = y + 1;

    } else if (Direction.D.equals(position)) {
        nextLocation[0] = x - 1; // 向下走, x - 1, y + 1
        nextLocation[1] = y + 1;

    } else if (Direction.T.equals(position)) {
        nextLocation[0] = x + 1; // 向上走, x + 1, y - 1
        nextLocation[1] = y - 1;
    }

    return nextLocation;
}

/**
 * <p>
 * Description: 得到下一步的方向
 * </p>
 * @param lastDirection
 * @param x
 * @param y
 */
private static Direction getNextDirection(Direction lastDirection, int x, int y) {
    if (x == 2 && y == 2) {
        System.out.println();
    }
    if (!(x == 0 || y == 0 || x == SIZE - 1 || y == SIZE - 1)) {
        return lastDirection;
    }

    if (x == 0 && y == 0) {
        return Direction.H;
    }

    if (x + y < SIZE - 1) { // 前半程的方向判断
        if (x == 0 && y % 2 == 0) {
            return Direction.T;

        } else if (x == 0 && y % 2 != 0) {
            return Direction.V;

        } else if (y == 0 && x % 2 != 0) {
            return Direction.D;

        } else if (y == 0 && x % 2 == 0) {
            return Direction.H;
        }

    } else { // 后半程的方向判断
        if (SIZE % 2 == 0) { // 注意此处. 由于SIZE的%2不同, 带来了对后半程的方向的逻辑不一样.
            if (x == SIZE - 1 && y % 2 == 0) {
                return Direction.D;

            } else if (x == SIZE - 1 && y % 2 != 0) {
                return Direction.V;

            } else if (y == SIZE - 1 && x % 2 != 0) {
                return Direction.T;

            } else if (y == SIZE - 1 && x % 2 == 0) {
                return Direction.H;
            }

        } else {
            if (x == SIZE - 1 && y % 2 != 0) {
                return Direction.D;

            } else if (x == SIZE - 1 && y % 2 == 0) {
                return Direction.V;

            } else if (y == SIZE - 1 && x % 2 == 0) {
                return Direction.T;

            } else if (y == SIZE - 1 && x % 2 != 0) {
                return Direction.H;
            }
        }
    }
    return null; // 理论上不会有null返回的
}

enum Direction {
    H, // 水平走
    V, // 垂直走
    D, // 向下走  [斜向下的走]
    T, // 向上走  [斜向上的走]
}

}[/code]

[code="java"]package test;

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    for (int x = 1; x < 10; x++) {
        for (int y = 1; y < 10; y++) {
            if ((x + y) <= 10) {
                int lineNum = x + y - 1;

                int topOfLast = (lineNum - 1) * (lineNum) / 2;

                // if direction is true,up
                // otherwise, down
                boolean direction = lineNum % 2 != 0 ? true : false;

                if (direction) {
                    System.out.print("" + (topOfLast + y) + "  ");
                } else {
                    System.out.print("" + (topOfLast + lineNum - y + 1)
                            + "  ");
                }
            } else {
                int innerX = x;
                int innerY = y;
                int offsetX = 1;
                int offsetY = 8;

                innerX -= offsetX;
                innerY -= offsetY;

                int lineNum = innerX + innerY - 1;

                int loopNum = 0;
                int start = 8;
                for (int j = 1; j < lineNum; j++) {
                    loopNum += start;
                    start--;
                }
                int topOfLast = loopNum + 45;

                // if direction is true,up
                // otherwise, down
                boolean direction = lineNum % 2 == 0 ? true : false;

                if (direction) {
                    System.out.print("" + (topOfLast + 10 - x)
                            + "  ");                        
                } else {

                    System.out.print("" + (topOfLast + x - lineNum ) + "  ");
                }
            }
        }
        System.out.println();
    }

}

}[/code]

[code="java"]1 2 6 7 15 16 28 29 45

3 5 8 14 17 27 30 44 46

4 9 13 18 26 31 43 47 60

10 12 19 25 32 42 48 59 61

11 20 24 33 41 49 58 62 71

21 23 34 40 50 57 63 70 72

22 35 39 51 56 64 69 73 78

36 38 52 55 65 68 74 77 79

37 53 54 66 67 75 76 80 81 [/code]

这个题目有几个要点:
这个矩阵是两个斜的三角形
1
2 3
4 5 6

1.左半部分和右半部分是有区别的:
[code="java"]if ((x + y) <= 10)[/code]

2.你需要通过x,y判断前一行的最大值topOfLast(从斜的角度看)
左边部分:
[code="java"]int lineNum = x + y - 1;

int topOfLast = (lineNum - 1) * (lineNum) / 2;[/code]

右边部分(我想这一块还可以改进的):
[code="java"]int innerX = x;

int innerY = y;

int offsetX = 1;

int offsetY = 8;

innerX -= offsetX;

innerY -= offsetY;

int lineNum = innerX + innerY - 1;

int loopNum = 0;

int start = 8;

for (int j = 1; j < lineNum; j++) {

loopNum += start;

start--;

}

int topOfLast = loopNum + 45; [/code]

3.判断从斜的角度来看,这一行的方向是向上的,还是向下的,这个可以通过(x+y)%2是否为0来判断,并且左半部分和右半部分是不一样的。

4.找到一个不会变的参考,当求左半部分时,可以用y作为参考,当求右半部分时,用x作为参考

这样就可以通过x和y确定这一个cell对应的值了。

仅供参考 :)

这题不用数组的话,还是有点挑战性的

fishbottle兄,
你的程序当行数是偶数时,有点问题哦(例如是6行6列)

有可能吧,这个没有写得那么有扩展性。

里面有些参数是只争对行数为9的时候的。

比如:
[color=darkred][/color]
[code="java"]int offsetX = 1;

int offsetY = 8; [/code]

[code="java"]int start = 8;[/code]

[code="java"]int topOfLast = loopNum + 45; [/code]

今天下午推了一下,还真有点麻烦
右半部的值不是与纵横坐标成线性关系
代码就直接在fishbottle兄的程序上改了一下 :oops:
顺便做了推广
[code="java"]
public class PrintNumber {

public static void main(String[] args) {
    //a matrix of ROW*ROW
    final int ROW=9;

    for (int x = 1; x < ROW+1; x++) {
        for (int y = 1; y < ROW+1; y++) {
            if ((x + y) <= ROW+1) {
                int lineNum = x + y - 1;
                int topOfLast = (lineNum - 1) * (lineNum) / 2;
                boolean direction = lineNum % 2 != 0 ? true : false;
                if (direction) {
                    System.out.print(String.format("%3d", (topOfLast + y)));
                } else {
                    System.out.print(String.format("%3d", (topOfLast + lineNum - y + 1)));
                }
            } else {
                int innerX = x;
                int innerY = y;
                int offsetX = 1;
                int offsetY = ROW-1;
                innerX -= offsetX;
                innerY -= offsetY;
                int lineNum = innerX + innerY - 1;
                int loopNum = 0;
                int start = ROW-1;
                for (int j = 1; j < lineNum; j++) {
                    loopNum += start;
                    start--;
                }
                boolean direction = lineNum % 2 == 0 ? true : false;
                if(ROW%2!=0){
                    if (direction) {
                        System.out.print(String.format("%3d", ROW*ROW-(ROW-(x+y-ROW))*(ROW-(x+y-ROW)+1)/2 +y-ROW));
                    } else {
                        System.out.print(String.format("%3d", (ROW*ROW-(ROW-(x+y-ROW)+1)*(ROW-(x+y-ROW)+2)/2+1 - y+ROW)));
                    }
                }else{
                    if (direction) {
                        System.out.print(String.format("%3d", (ROW*ROW-(ROW-(x+y-ROW)+1)*(ROW-(x+y-ROW)+2)/2+1 - y+ROW)));
                    } else {

                        System.out.print(String.format("%3d", ROW*ROW-(ROW-(x+y-ROW))*(ROW-(x+y-ROW)+1)/2 +y-ROW));
                    }
                }

            }
        }
        System.out.println();
    }
}

}

[/code]

呵呵,
这样就可以适应许多种情况了,
多谢fivestarwy的改进版.

[code="java"]String.format("%3d", (topOfLast + y))[/code]

这句很经典,fivestarwy兄写程序太仔细了。