题目:
Consider an infinite square grid. Each square in the grid can be represented by a pair of integer coordinates that specify its row and column.
We will fill the entire grid with a spiral of positive integers. We will start by writing the number 1 into the square in row 0, column 0. Then we will write the number 2 into the square in row 0, column 1. From there, the spiral will continue in a counter-clockwise direction. The next few numbers are placed as shown in the scheme below:
columns
-3 -2 -1 0 1 2 3
--------------------
-3 | 37 36 35 34 33 32 31
-2 | 38 17 16 15 14 13 30
-1 | 39 18 5 4 3 12 29
rows 0 | 40 19 6 1 2 11 28
1 | 41 20 7 8 9 10 27
2 | 42 21 22 23 24 25 26
3 | 43 44 45 46 .. .. ..
Your task will be to return a String[] containing a pretty-printed version of a rectangular part of the filled grid.
More precisely, you will be given four ints row1, col1, row2, and col2. Here, row1,col1 will be the coordinates of the top left cell, and row2,col2 the coordinates of the bottom right cell to be displayed.
The returned String[] must be formatted according to the following rules:
The String[] contains one element for each row of the displayed rectangle. The elements are ordered by the row coordinate they describe.
Each element is a concatenation of space-separated tokens, each describing a cell in the corresponding row. The tokens are ordered by the column coordinates of cells they describe.
All tokens in the entire output have the same length.
The length of a token is minimal, i.e., equal to the number of digits in the largest number displayed.
Tokens that contain numbers with fewer digits are padded from the left using spaces.
Definition
Class:
PrettyPrintASpiral
Method:
getWindow
Parameters:
int, int, int, int
Returns:
String[]
Method signature:
String[] getWindow(int row1, int col1, int row2, int col2)
(be sure your method is public)
Notes
-
The constraints guarantee that the returned String[] will have at most 50 elements, and the length of each element will be at most 50.
Constraints
-
row1 will be between -5,000 and 5,000, inclusive.
-
col1 will be between -5,000 and 5,000, inclusive.
-
row2 will be between -5,000 and 5,000, inclusive.
-
col2 will be between -5,000 and 5,000, inclusive.
-
row2-row1 will be between 0 and 49, inclusive.
-
col2-col1 will be between 0 and 4, inclusive.
Examples
0)
0
0
0
0
Returns: {"1" }
The spiral starts at coordinates (0,0).
1)
-1
-2
-1
1
Returns: {"18 5 4 3" }
Note that the single-digit values are now padded with spaces.
2)
-2
2
0
3
Returns: {"13 30", "12 29", "11 28" }
3)
-3
-3
2
0
Returns:
{"37 36 35 34",
"38 17 16 15",
"39 18 5 4",
"40 19 6 1",
"41 20 7 8",
"42 21 22 23" }
题目排版有点乱,是tournament 183期500分题。题目意思大概是:有一个逆时针递增排列的字符串数组,给定两个坐标(row1,col1)(row2,col2),要求输出这两个坐标之间的数字。
我的思路:先根据坐标构造完整的int数组,该数组就是逆时针递增排列的,构造方法大致是:先算出数组有几层,然后依次构造每层的数字。然后截取符合要求的小数组,再转换成String数组。
代码:
package jyu.topcoder._183;
public class PrettyPrintASpiral {
public static void main(String[] args) {
PrettyPrintASpiral ppa = new PrettyPrintASpiral();
String[] answers = ppa.getWindow(-3, -3, 2, 0);
for (int i = 0; i < answers.length; i++) {
System.out.println(answers[i]+"1");
}
}
public String[] getWindow(int row1, int col1, int row2, int col2){
int length = getLength(row1, col1, row2, col2);
int[][] All = new int[length + 1][length + 1]; //使用int数字来保存循环数字
//计算有几圈数字
int zero = length/2;
//中间的数字为1
All[zero][zero] = 1;
int max = (length + 1) * (length + 1);
//依次给每圈数字赋值
for (int i = 0; i < zero; i++) {
int index = (length - i);
int minLenght = length -2*i;
//底部
for (int j = 0; j < minLenght; j++) {
All[index][index - j] = max;
max--;
}
//左边
for (int j = 0; j < minLenght; j++) {
All[index - j][length - index] = max;
max--;
}
//上边
for (int j = 0; j < minLenght; j++) {
All[length - index][length - index + j] = max;
max--;
}
//右边
for (int j = 0; j < minLenght; j++) {
All[length - index + j][index] = max;
max--;
}
}
int row = Math.abs(row1 - row2) + 1;
int col = Math.abs(col1 - col2) + 1;
//将各个索引转换为正常索引
row1 = zero + row1;
row2 = zero + row2;
col1 = zero + col1;
col2 = zero + col2;
int[][] right = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
right[i][j] = All[row1 + i][col1 + j];
}
}
//将int数组转换为String数组
String[] answers = new String[row];
for (int i = 0; i < row; i++) {
String temp = "";
for (int j = 0; j < col; j++) {
if(right[i][j] < 10){
temp += " " + right[i][j]+" ";
}else
temp += right[i][j]+" ";
}
temp = temp.substring(0,temp.length()-1);
answers[i] = temp;
}
return answers;
}
//判断需要构造的数组的长度
public int getLength(int row1, int col1, int row2, int col2){
row1 = Math.abs(row1);
row2 = Math.abs(row2);
col1 = Math.abs(col1);
col2 = Math.abs(col2);
int a = Math.max(row1, col1);
int b = Math.max(row2, col2);
int c = Math.max(a, b);
return 2*c;
}
}
总结:这个代码花了我两个小时。。。。。 嗯 两个小时,TopCoder整个比赛时间才75分钟,看来我可以证明我没有编程天赋了,只求勤能补拙啦。看了下TopCoder的高手代码,有一位是跟我的思路差不多,先构造,再截取,但是构造方法不一样。另一位是根据规则直接生成答案(规则不清楚)。