问题描述
求个程序,打印出以下数据: 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
解决方案
跟楼上几位思路差不多~发现我的变量命名真是烂啊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;}}
解决方案二:
String.format("%3d", (topOfLast + y))这句很经典,fivestarwy兄写程序太仔细了。
解决方案三:
呵呵,这样就可以适应许多种情况了,多谢fivestarwy的改进版.
解决方案四:
今天下午推了一下,还真有点麻烦右半部的值不是与纵横坐标成线性关系代码就直接在fishbottle兄的程序上改了一下 顺便做了推广public class PrintNumber {public static void main(String[] args) {//a matrix of ROW*ROWfinal 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();}}}
解决方案五:
有可能吧,这个没有写得那么有扩展性。里面有些参数是只争对行数为9的时候的。比如:[color=darkred][/color]int offsetX = 1; int offsetY = 8; int start = 8;int topOfLast = loopNum + 45;
解决方案六:
这题不用数组的话,还是有点挑战性的fishbottle兄,你的程序当行数是偶数时,有点问题哦(例如是6行6列)
解决方案七:
这个题目有几个要点:这个矩阵是两个斜的三角形 1 2 3 4 5 61.左半部分和右半部分是有区别的:if ((x + y) <= 10)2.你需要通过x,y判断前一行的最大值topOfLast(从斜的角度看)左边部分:int lineNum = x + y - 1; int topOfLast = (lineNum - 1) * (lineNum) / 2;右边部分(我想这一块还可以改进的):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; 3.判断从斜的角度来看,这一行的方向是向上的,还是向下的,这个可以通过(x+y)%2是否为0来判断,并且左半部分和右半部分是不一样的。4.找到一个不会变的参考,当求左半部分时,可以用y作为参考,当求右半部分时,用x作为参考这样就可以通过x和y确定这一个cell对应的值了。仅供参考
解决方案八:
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, downboolean 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, downboolean direction = lineNum % 2 == 0 ? true : false;if (direction) {System.out.print("" + (topOfLast + 10 - x)+ " ");} else {System.out.print("" + (topOfLast + x - lineNum ) + " ");}}}System.out.println();}}}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
解决方案九:
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 + 1nextLocation[1] = y + 1;} else if (Direction.D.equals(position)) {nextLocation[0] = x - 1; // 向下走, x - 1, y + 1nextLocation[1] = y + 1;} else if (Direction.T.equals(position)) {nextLocation[0] = x + 1; // 向上走, x + 1, y - 1nextLocation[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, // 向上走 [斜向上的走]}}
解决方案十:
已经做出来了.. 其实前半程的很简单, 难的是后半程的, 而且, SIZE不一样, 后半程的判断逻辑也有不一样. [一直被卡在这个地方. 耗了很多时间.] 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
解决方案十一:
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, downboolean 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, downboolean 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();}}}明天再继续,暂时只能打一边,右边应该一样的