题目描述
方阵的主对角线之上称为"上三角"。
请你设计一个用于填充 n 阶方阵的上三角区域的程序。填充的规则是:使用 1,2,3.... 的自然数列,从左上角开始,按照顺时针方向螺旋填充。
例如:当 =3n=3 时,输出:
1 2 3
6 4
5
当 n=4 时,输出:
1 2 3 4
9 10 5
8 6
7
当 n=5 时,输出:
1 2 3 4 5
12 13 14 6
11 15 7
10 8
9
输入描述
要求用户输入整数 n (3≤n≤20)。
输出描述
输出方阵的上三角部分。
要求每个数据宽度为 4,右对齐。
输入输出样例
示例
输入
9
输出
1 2 3 4 5 6 7 8 9
24 25 26 27 28 29 30 10
23 39 40 41 42 31 11
22 38 45 43 32 12
21 37 44 33 13
20 36 34 14
19 35 15
18 16
17
运行限制
最大运行时间:1s
最大运行内存: 256M
解题思路
这题其实不难,但是却困了我好久,我觉得最重要的地方就在于处理边界问题.
1,首先要确定模拟的方式,是采用左开右闭还是左闭右开,我觉得的这个还是很重要的,如果杂乱无章很容易造成越界问题,然后东改改西改改一直找不到问题所在.
2,接着就是中心的处理问题,因为我采用的是左闭右开原则,所以当x == y 时(即行和列相同时)访问不
到该位置,需要单独做出处理
错误示范
![](https://i-blog.csdnimg.cn/blog_migrate/60ea582ff661dd1324b7e7e5a3148af1.png)
一开始没有处理中心点问题,所以导致蓝桥oj一直编译不过,粗略对比发现两组输出数据都是一样的呀,奇怪了怎么会编译不过去呢!后来仔细观察才发现中间有一个点没有处理到,而这个点恰好是当行和列相同的时候,所以只需要在最后判断一下行和列是否相等再单独判断一下即可,下面来看正确代码.
AC代码
import java.util.Scanner;
public class 上三角方阵 {
static int[][] arr = new int[25][25];
static int num = 1;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
dfs(1, n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i + 1; j++) {
System.out.print(" "+arr[i][j]);
}
System.out.println();
}
}
private static void dfs(int x, int y) {
if (y < x) {
return;
}
//处理边界问题很重要,这里一律采用左闭右开原则
//处理上边界
for (int i = x; i < y; i++) {
arr[x][i] = num++;
}
//处理斜边
int dy = y;
for (int i = x; i < y; i++) {
arr[i][dy] = num++;
--dy;
}
//处理左边界
for (int i = y; i >= x + 1; i--) {
arr[i][x] = num++;
}
//内层循环
dfs(x + 1, y - 2);
//最中间的那个点
if (x == y) {
arr[x][y] = num++;
}
}
}
什么是左开右闭,左闭右开?
为了考虑到刚学编程的人,我来解释一下
学过数学的都知道,顾名思义,左开右闭就是不等于左边第一个,但是会等于右边最后一个,如下图
![](https://i-blog.csdnimg.cn/blog_migrate/6fcca554b4582ba20fc17dc34f7b2f20.png)
同理,左闭右开,即等于左边第一个,不等于右边最后一个,如下图
![](https://i-blog.csdnimg.cn/blog_migrate/d9b0d382d7b118133a0a788739fda275.png)
相似题目
为了加深印象以及更好的理解该类题目,我找到了力扣上一题相似的题目
这题我也写了题解,可以参考一下!