最大正方形
【题目描述】
给定一个 R 行 C 列的 01 矩阵,求一个最大的正方形全 1 子矩阵,并输出该最大正方形子矩阵的面积。
【输入】
第一行给出两个正整数 R,C,表示矩阵有 R 行 C 列;
接下来 R 行 C 列给出这个 01 矩阵,行内相邻两元素用一个空格隔开。
【输出】
一个数,最大正方形子矩阵的的面积(即 1 的个数) 。
【输入输出样例】
matrix.in matrix.out
5 8
0 0 0 1 1 1 0 1
1 1 0 1 1 1 1 1
0 1 1 1 1 1 0 1
1 0 1 1 1 1 1 0
1 1 1 0 1 1 0 1
9
【数据 范围限制 】
20%的数据,R,C<=20;
40%的数据,R,C<=100;
100%的数据,R,C<=1000。
【解析】:求最大正方形自矩阵面积 转换为 求最大边长
var maxSidelength;
对每个值=1的点进行遍历:
判断它能否作为最小正方形矩阵右上顶点
【解析】:求最大正方形自矩阵面积 转换为 求最大边长
var maxSidelength;
对每个值=1的点进行遍历:
判断它能否作为最小正方形矩阵右上顶点
if(min(a,b,c,d)=0){
do nothing;
}else{
d=min(a,b,c,d)+1;//用右上定点的值来存放边长
maxSidelength=d>maxSidelength?d:maxSidelength;
}
if(min(a,b,c,d)=0){
do nothing;
}else{
d=min(a,b,c,d)+1;//用右上定点的值来存放边长
maxSidelength=d>maxSidelength?d:maxSidelength;
}
package chang57;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.Scanner;
public class Matrix {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(new File("matrix.in"));
Writer wr = new FileWriter("martrix.out");
//声明二维数组存放(0,1)矩阵
int m = sc.nextInt();
int n = sc.nextInt();
int[][] arr = new int[m][n];
//两次循环为数组初始化
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
arr[i][j] = sc.nextInt();
}
}
//变量borderSideLength存放最大边长
int borderSideLength = 0;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (arr[i][j] == 1) {
//对以arr[i][j]为定点的右上最小正方形矩阵其他三个顶点取最小值
int temp = min(arr[i][j - 1], arr[i - 1][j], arr[i - 1][j - 1]);
if (temp != 0) {//最小值为0,则不能作为所求目标的边
arr[i][j] = temp + 1;//将最小值+1赋值给右上顶点,以便向上运算
if (arr[i][j] > borderSideLength)//如果,右上顶点值>边长,则更新边长
borderSideLength = arr[i][j];
}
}
}
}
wr.write(String.valueOf(borderSideLength * borderSideLength));
sc.close();
wr.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
//计算三个整数最小值
static int min(int a, int b, int c) {
a = a < b ? a : b;
a = a < c ? a : c;
return a;
}
}