疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:
给出数字个数n 和行数m (0 < n ≤ 999,0 < m ≤ 999),从左上角的1开始,按照顺时针螺旋向内写 方式,依次写出2,3...n,最终形成一个m行矩阵 。
小明对这个矩阵有些要求 :
1.每行数字的个数一样多
2.列的数量尽可能少
3.填充数字时优先填充外部
4.数字不够时,使用单个*号占位
输入描述:
两个整数,空格隔开,依次表示n、m
输出描述:
符合要求的唯一矩阵
题目解析:循环遍历,一个大循环(顺时针一次)包括从左到右,从上到下,从右到左,从下到上四次遍历,理清楚每次遍历的起始点和终止点就行。起始点其实就是和上一次遍历的终点紧密相关,终点和循环的次数相关。(额外注意n< m的情况,以及 n % m != 0 的情况)
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// int n = 9;
// int m = 4;
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
if (n < m) {
int count = 1;
for (int i = 0; i < m; i++) {
if (count <= n) {
System.out.println(count++);
} else {
System.out.println("*");
}
}
return;
}
int p = (n % m == 0) ? n / m : n / m + 1;
int[][] nums = new int[m][p];
int count = 1;
// 每次循环的开始,第一次是(0,0)坐标,第二次(1,1)...(startX,startY)
int startX = 0;
int startY = 0;
// loop记录已经循环的次数,方便计算终止条件
int loop = 0;
// i,j 遍历的当前位置(i,j)
int i;
int j;
int maxLoop = p / 2;
while (maxLoop > 0) {
for (j = startY; j < p - loop - 1; j++) {
if (count <= n) {
nums[startX][j] = count++;
}
}
for (i = startX; i < m - loop - 1; i++) {
if (count <= n) {
nums[i][j] = count++;
}
}
for (j = p - loop - 1; j > startY; j--) {
if (count <= n) {
nums[i][j] = count++;
}
}
for (i = m - loop - 1; i > startX; i--) {
if (count <= n) {
nums[i][j] = count++;
}
}
loop++;
startY++;
startX++;
maxLoop--;
}
// 不够整除,需要额外遍历一列,注意这一列的终止条件
if (p % 2 == 1 && count <= n) {
i = startX;
for (int k = startX; k <= m - loop - 1; k++) {
nums[i][k] = count++;
}
}
// 输出结果,注意空格位置
for (int k = 0; k < m; k++) {
for (int l = 0; l < p; l++) {
if (nums[k][l] == 0) {
System.out.print("*");
} else {
System.out.print(nums[k][l]);
}
if (l != p - 1) {
System.out.print(" ");
}
}
System.out.println();
}
}
}