求个程序,打印出以下数据:
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兄写程序太仔细了。