方阵的主对角线之上称为“上三角”。
请你设计一个用于填充n阶方阵的上三角区域的程序。填充的规则是:使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。
例如:当n=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
程序运行时,要求用户输入整数n(3~20)
程序输出:方阵的上三角部分。
要求格式:每个数据宽度为4,右对齐。
public class gaozhi9 {
/*
*
* 可以这样看:把所输出的上三角看作是一个个三角形套在一起;
* 1.对于每一个三角形三条边上的数的求法是一样的;(所以 对此问题可以使用递归)
* 2.上面的一边上的数一定是连续的;(第i个三角形的上边)
* 3.之后就要求三角形的斜边的数(第i个三角形的斜边)
* 4.之后再求三角形的另一条直角边上的数(第i个三角形的左边)
*
* a数组保存各个点的元素,i就表示当前从第几行开始(即第i个三角形,因为从每行都可以开始一个三角形),
* n表示总共有多少行
* m表示下次递归应开始的数
*
* 本程序存在的问题:对每个数据的宽度为4,没能够理解,只用了制表符进行了数据的控制
*
* 你发给我没有怎么看,用java写的基本没用java的独有的特性,都是一些基本的函数
* 经验证没有错误
*/
/*
*
* 函数void f(int[][] a, int i, int n, int m, int s)用来对第i个三角形进行赋值
* 对于第i个三角形易知:
* 1.第i行的上边连续的数个数为n-3*(n -1);
* 2.当列的值等于i的值时,对于斜边的赋值已经完成
* 3.对于左边的直角边,其列的值等于i
*/
public static void f(int[][] a, int i, int n, int m, int s) {
int k = 1;
int j = i;
//s代表此上三角矩阵中最大的那个数,若达到s则程序不必再运行,没达到s则继续进行运行
if (m <= s) {
//对第i个三角形的上边赋值
for (k = i; k <= n - 2 * (i - 1); k++) {
if(m > s) break;
a[i][k] = m++;
}
//将k的值置为矩阵中第i+1行的最后一列
k -= 2;
//对第i个三角形斜边赋值
for (; k >= j; k--) {
//判断m是否大于s,若大于s,则不再进行赋值
if(m > s) break;
a[++i][k] = m++;
}
//对第i个三角形左边进行赋值
for (int num = i - 1; num > j; num--) {
if(m > s ) break;
a[num][j] = m++;
}
//若m<=s,则说明还有三角形,应继续运行
if(m <= s) {
f(a, j + 1, n, m, s);
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int i = 0;
int j = 0;
int[][] a = new int[n + 1][n + 1];
//将a数组中所有的元素初始化0
for (i = 1; i <= n; i++) {
for (j = 1; j <= n - i + 1; j++)
a[i][j] = 0;
}
//s表示矩阵中最大的那个数
int s = n * (n + 1) / 2;
//调用函数进行运算,并将运算结果存放在数组a中
f(a, 1, n, 1 , s);
//对数组a进行输出
for (i = 1; i <= n; i++) {
for (j = 1; j <= n - i + 1; j++)
System.out.printf("%4s",a[i][j]);
System.out.println();
}
}
}