目录
- 题目
- 分析
- 代码
题目
选自牛客网
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
分析
-
导入Scanner类:
import java.util.Scanner;
这行代码导入了Java的
Scanner
类,用于从控制台读取输入。 -
主类和主方法:
public class Main { public static void main(String[] args) { // ... } }
这是Java程序的入口点。
-
读取矩阵大小:
int n = in.nextInt();
从控制台读取一个整数
n
,表示矩阵的大小。 -
初始化矩阵和前缀和数组:
int[][] nums = new int[n][n]; int[][] sum = new int[n + 1][n + 1];
nums
是一个二维数组,用于存储矩阵中的元素(0或1)。sum
是一个二维数组,用于存储矩阵中每个子矩阵的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'; sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + nums[i][j]; } }
这个循环读取每一行的输入,将字符转换为整数(0或1),并计算每个子矩阵的1的总数。
-
计算完美矩形区域的数量:
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的总数,然后检查它们是否相等。如果相等,则增加完美矩形区域的计数。 -
关闭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();
}
}
图片:
加油少年