每日一 练,java

题目

选自牛客网
1.小美的平衡矩阵
小美拿到了一个𝑛∗𝑛的矩阵,其中每个元素是 0 或者 1。
小美认为一个矩形区域是完美的,当且仅当该区域内 0 的数量恰好等于 1 的数量。现在,小美希望你回答有多少个i∗i的完美矩形区域。你需要回答1≤i≤n的所有答案。

输入描述:
第一行输入一个正整数n,代表矩阵大小。
接下来的n行,每行输入一个长度为n的 01 串,用来表示矩阵。
1<= n <= 200
输出描述:
输出n行,第i行输出i*i的完美矩形区域的数量。
示例1
输入例子:
4
1010
0101
1100
0011
输出例子:
0
7
0
1

分析

  1. 导入Scanner类

    import java.util.Scanner;
    

    这行代码导入了Java的Scanner类,用于从控制台读取输入。

  2. 主类和主方法

    public class Main {
        public static void main(String[] args) {
            // ...
        }
    }
    

    这是Java程序的入口点。

  3. 读取矩阵大小

    int n = in.nextInt();
    

    从控制台读取一个整数n,表示矩阵的大小。

  4. 初始化矩阵和前缀和数组

    int[][] nums = new int[n][n];
    int[][] sum = new int[n + 1][n + 1];
    

    nums是一个二维数组,用于存储矩阵中的元素(0或1)。sum是一个二维数组,用于存储矩阵中每个子矩阵的1的总数,增加了一行一列作为边界,方便计算。

  5. 填充矩阵和计算前缀和

    for (int i = 0; i < n; i++) {
        String row = in.next();
        for (int j = 0; j < n; j++) {
            nums[i][j] = row.charAt(j) - '0';
            sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + nums[i][j];
        }
    }
    

    这个循环读取每一行的输入,将字符转换为整数(0或1),并计算每个子矩阵的1的总数。

  6. 计算完美矩形区域的数量

    for (int size = 1; size <= n; size++) {
        int perfectCount = 0;
        for (int startRow = 0; startRow <= n - size; startRow++) {
            for (int startCol = 0; startCol <= n - size; startCol++) {
                int ones = sum[startRow + size][startCol + size] - sum[startRow][startCol + size] - sum[startRow + size][startCol] + sum[startRow][startCol];
                int zeros = size * size - ones;
                if (ones == zeros) {
                    perfectCount++;
                }
            }
        }
        System.out.println(perfectCount);
    }
    

    这个循环从1到n,计算每个大小的正方形区域。对于每个可能的正方形区域,计算其1的总数和0的总数,然后检查它们是否相等。如果相等,则增加完美矩形区域的计数。

  7. 关闭Scanner

    in.close();
    

    关闭Scanner对象,释放资源。

这个程序的逻辑是:

  • 读取矩阵大小和矩阵元素。
  • 计算每个子矩阵的1的总数。
  • 对于每个可能的正方形区域,检查其是否是完美的(0和1的数量相等)。
  • 输出每种大小的完美正方形区域的数量。

这是一个有效的解决方案,可以正确地解决小美平衡矩阵问题。

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[][] nums = new int[n][n];
        int[][] sum = new int[n + 1][n + 1]; // 增加一行一列作为边界,方便计算

        for (int i = 0; i < n; i++) {
            String row = in.next();
            for (int j = 0; j < n; j++) {
                nums[i][j] = row.charAt(j) - '0'; // 将字符转换为整数0或1
                sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + nums[i][j];
            }
        }

        for (int size = 1; size <= n; size++) { // 从1到n,计算每个大小的正方形区域
            int perfectCount = 0;
            for (int startRow = 0; startRow <= n - size; startRow++) {
                for (int startCol = 0; startCol <= n - size; startCol++) {
                    int ones = sum[startRow + size][startCol + size] - sum[startRow][startCol + size] - sum[startRow + size][startCol] + sum[startRow][startCol];
                    int zeros = size * size - ones; // 计算0的个数
                    if (ones == zeros) { // 如果0和1的个数相等
                        perfectCount++;
                    }
                }
            }
            System.out.println(perfectCount); // 输出结果
        }

        in.close();
    }
}

图片:
美好的记忆
加油少年

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布说在见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值