螺旋数字矩阵

题目描述

疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:

给出数字个数 n (0 < n ≤ 999)和行数 m(0 < m ≤ 999),从左上角的 1 开始,按照顺时针螺旋向内写方式,依次写出2,3,....,n,最终形成一个 m 行矩阵。

小明对这个矩阵有些要求:

  1. 每行数字的个数一样多
  2. 列的数量尽可能少
  3. 填充数字时优先填充外部
  4. 数字不够时,使用单个 * 号占位

输入描述

两个整数,空格隔开,依次表示 n、m

输出描述

符合要求的唯一矩阵

输入:

9 4

输出:

1 2 3
* * 4
9 * 5
8 7 6

import java.util.Scanner;

/**
 * <h1>螺旋数字矩阵</h1>
 *
 *  分析:
 *      num的个数: n
 *      行数: m
 *      列数: l = n/m + 1
 *      num 和 * 的总数: m*l
 *      * 的个数: x = l*m - n
 *
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String input = in.nextLine();
            String[] inputs = input.split("\\s+");
            int n = Integer.parseInt(inputs[0]);
            int m = Integer.parseInt(inputs[1]);
            process(n, m);
        }
    }

    private static void process(int n, int m) {
        // 列数
        int l = n / m + 1;

        // 定义二维数组
        int x = m;
        int y = l;
        int[][] intArr = new int[x][y];

        // 从1开始填充
        int num = 1;

        // 循环一次,顺时针转一圈
        int k = 0;
        while (true) {
            // 填充的数字大于二维数组的容量时,结束
            if (num > l * m) {
                break;
            }
            // 顺时针转一圈
            // 上
            for (int i = k; i < y - 1; i++) {
                intArr[k][i] = num;
                num++;
                if (num > l * m) {
                    break;
                }
            }

            // 右
            for (int i = k; i < x - 1; i++) {
                intArr[i][y - 1] = num;
                num++;
                if (num > l * m) {
                    break;
                }
            }

            // 下
            for (int i = y - 1; i > k; i--) {
                intArr[x - 1][i] = num;
                num++;
                if (num > l * m) {
                    break;
                }
            }

            // 左
            for (int i = x - 1; i > k; i--) {
                intArr[i][k] = num;
                num++;
                if (num > l * m) {
                    break;
                }
            }

            x--;
            y--;
            k++;
        }

        // 遍历数组
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < l; j++) {

                // 对应位置的数值大于n时,打印“*” -- 加了制表符,格式清晰
                if (intArr[i][j] > n) {
                    System.out.print("*" + "\t");
                } else {
                    System.out.print(intArr[i][j] + "\t");
                }
            }
            System.out.println();
        }
    }
}

 

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值