给定一个的矩阵matrix,在这个矩阵中,只有0和1两种值,返回边框全是1的最大正方形的边长长度、
例如
0 1 1 1 1
0 1 0 0 1
0 1 0 0 1
0 1 1 1 1
0 1 0 1 1
其中,边框全是1的最大正方形的大小为,所以返回4
[要求]
时间复杂度为,空间复杂度为
第一行一个整数N。表示矩阵的长宽。
接下来N行,每行N个整数表示矩阵内的元素
输出一个整数表示答案
5 0 1 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 1 0 1 0 1 1
4
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int[][] arr = new int[n][n]; for(int i = 0; i < n; i++){ String[] line = br.readLine().split(" "); for(int j = 0; j < n; j++) arr[i][j] = Integer.parseInt(line[j]); } int[][] right = new int[n][n]; int[][] down = new int[n][n]; for(int i = n - 1; i >= 0; i--) { for(int j = n - 1; j >= 0; j--) { if(i == n - 1) down[i][j] = arr[i][j]; else down[i][j] = arr[i][j] == 0? 0: down[i + 1][j] + 1; if(j == n - 1) right[i][j] = arr[i][j]; else right[i][j] = arr[i][j] == 0? 0: right[i][j + 1] + 1; } } int maxEdgeLength = 1; // 枚举正方形左上角顶点的位置 for(int row = 0; row < n; row++){ for(int col = 0; col < n; col++){ if(arr[row][col] == 0) continue; for(int border = Math.min(n - row, n - col); border >= 1; border--){ // 看边长够不够border if(right[row][col] >= border && down[row][col] >= border && right[row + border - 1][col] >= border && down[row][col + border - 1] >= border){ maxEdgeLength = Math.max(maxEdgeLength, border); break; } } } } System.out.println(maxEdgeLength); } }
#include <bits/stdc++.h> using namespace std; int main(){ int n, Max=0, s1, s2; cin>>n; int a[n+1][n+1], row[n+1][n+1], col[n+1][n+1]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ cin>>a[i][j]; row[i][j] = row[i][j-1] + a[i][j]; col[i][j] = col[i-1][j] + a[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ for(int l=Max+1;l<=min(n-i+1,n-j+1);l++){ s1 = row[i][j+l-1] - row[i][j-1]; s2 = col[i+l-1][j] - col[i-1][j]; if(s1!=l || s2!=l) break; s1 = row[i+l-1][j+l-1] - row[i+l-1][j-1]; s2 = col[i+l-1][j+l-1] - col[i-1][j+l-1]; if(s1==l && s2==l) Max = max(Max, l); } } cout<<Max<<endl; return 0; }
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[][] arr = new int[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++) { arr[i][j] = scanner.nextInt(); } } int[][] right = new int[n][n]; int[][] down = new int[n][n]; for(int i=n-1;i>=0;i--) { for(int j=n-1;j>=0;j--) { if(i==n-1) { down[i][j] = arr[i][j]; }else { down[i][j] = arr[i][j]==0? 0:down[i+1][j]+1; } if(j==n-1) { right[i][j] = arr[i][j]; }else { right[i][j] = arr[i][j]==0? 0:right[i][j+1]+1; } } } int max = 0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++) { int m = Math.min(down[i][j], right[i][j]); for(int k=m-1;k>=0;k--) { if(right[i+k][j] >= k+1 && down[i][j+k]>=k+1) { max = Math.max(max, k+1); break; } } } } System.out.println(max); } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] m = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { m[i][j] = sc.nextInt(); } } System.out.println(getMaxMatrix(m)); sc.close(); } //以每一个点为左上角,尝试是否存在一个长度为1~N的正方形 //由于使用了预处理,时间复杂度变为O(N^3) public static int getMaxMatrix(int[][] m) { if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) return 0; if (m.length == 1) return m[0][0] == 1 ? 1 : 0; int len = m.length; int[][] right = new int[len][len]; int[][] down = new int[len][len]; preProcess(right, down, m); int res = 0; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { for (int n = 1; n <= len; n++) { if (hasNSquare(right, down, n, i, j)) res = Math.max(res, n); } } } return res; } //预处理,使right[i][j]代表从m[i][j]开始往右最多出现了几个连续的1 //down[i][j]代表从m[i][j]开始往下最多出现了几个连续的1 public static void preProcess(int[][] right, int[][] down, int[][] m) { int len = m.length-1; right[len][len] = m[len][len] == 1 ? 1 : 0; down[len][len] = m[len][len] == 1 ? 1 : 0; for (int i = len-1; i >= 0; i--) { if (m[i][len] == 1) { right[i][len] = 1; down[i][len] = 1 + down[i+1][len]; } if (m[len][i] == 1) { right[len][i] = 1 + right[len][i+1]; down[len][i] = 1; } } for (int i = len-1; i >= 0; i--) { for (int j = len - 1; j >= 0; j--) { if (m[i][j] == 1) { right[i][j] = right[i][j+1] + 1; down[i][j] = down[i+1][j] + 1; } } } } //判断以m[i][j]为左上角,边长为n且边界都是1的正方形是否存在 public static boolean hasNSquare(int[][] right, int[][] down, int n, int i, int j) { if (right[i][j] >= n && down[i][j] >= n) { if (i + n - 1 < right.length && j + n - 1 < down.length) { if (right[i+n-1][j] >= n && down[i][j+n-1] >= n) return true; } } return false; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] m = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { m[i][j] = sc.nextInt(); } } System.out.println(getMaxBorderSize(m)); } public static void preprocess(int[][] m, int[][] right, int[][] down) { int row = m.length, col = m[0].length; // set the last column of right and the last row of down for (int i = 0; i < row; i++) { right[i][col - 1] = m[i][col - 1]; } for (int j = 0; j < col; j++) { down[row - 1][j] = m[row - 1][j]; } // set the last row of right[][] for (int j = col - 2; j >= 0; j--) { if (m[row - 1][j] == 1) { right[row - 1][j] = right[row - 1][j + 1] + 1; } else { right[row - 1][j] = 0; } } // set the last column of down[][] for (int i = row - 2; i >= 0; i--) { if (m[i][col - 1] == 1) { down[i][col - 1] = down[i + 1][col - 1] + 1; } else { down[i][col - 1] = 0; } } // set the other position of right[][] and down[][] for (int i = row - 2; i >= 0; i--) { for (int j = col - 2; j >= 0; j--) { if (m[i][j] == 1) { right[i][j] = right[i][j + 1] + 1; down[i][j] = down[i + 1][j] + 1; } else { right[i][j] = 0; down[i][j] = 0; } } } } public static int getMaxBorderSize(int[][] m) { int[][] right = new int[m.length][m[0].length]; int[][] down = new int[m.length][m[0].length]; preprocess(m, right, down); int n = Math.min(m.length, m[0].length); for (int size = n; size >= 0; size--) { if (hasSizeOfBorder(size, right, down)) { return size; } } return 0; } private static boolean hasSizeOfBorder(int size, int[][] right, int[][] down) { for (int i = 0; i < right.length - size + 1; i++) { for (int j = 0; j < right[0].length - size + 1; j++) { if (right[i][j] >= size && down[i][j] >= size && right[i + size - 1][j] >= size && down[i][j + size - 1] >= size) { return true; } } } return false; } }
import java.util.Scanner; public class Main{ //根据m矩阵,设置right与down矩阵,right[i][j]表示m[i][j]的右边有多少个连续的1,包括自身 //down[i][j]表示m[i][j]的下边有多少个连续的1,包括自身 public static void setRightAndDown(int[][] m, int [][] right, int[][] down) { int rowNum = m.length; int colNum = m[0].length; //初始化右下角位置 right[rowNum - 1][colNum - 1] = m[rowNum - 1][colNum - 1]; down[rowNum - 1][colNum - 1] = m[rowNum - 1][colNum - 1]; //初始化最后一行 for (int col = colNum - 2; col >= 0; col--) { if (m[rowNum - 1][col] == 1) { right[rowNum - 1][col] = right[rowNum - 1][col + 1] + 1; down[rowNum - 1][col] = 1; } } //初始化最后一列 for (int row = rowNum - 2; row >= 0; row--) { if (m[row][colNum - 1] == 1) { right[row][colNum - 1] = 1; down[row][colNum - 1] = down[row + 1][colNum - 1] + 1; } } //其他位置,从右向左,从下到上设置值 for (int row = rowNum - 2; row >= 0; row--) { for (int col = colNum - 2; col >= 0; col--) { if (m[row][col] == 1) { right[row][col] = right[row][col + 1] + 1; down[row][col] = down[row + 1][col] + 1; } } } } public static int getMaxSize(int[][] m) { int[][] right = new int[m.length][m[0].length]; int[][] down = new int[m.length][m[0].length]; setRightAndDown(m, right, down); for (int length = Math.min(m.length, m[0].length); length >= 1; length--) { //对于每个边长,看是否存在以该值作为边长的矩阵,满足四周全为1 //因为要找最大边长,所以从大到小找 if (hasSizeOfBorder(length, right, down)) { return length; } } return 0; } //该函数实现传入一个边长值,根据right与down矩阵,判断是否存在正方形满足四周全为1 public static boolean hasSizeOfBorder(int length, int[][] right, int[][] down) { for (int row = 0; row + length - 1 <= right.length - 1; row++) { for(int col = 0; col + length - 1 <= right[0].length - 1; col++) { //row,col代表左上方的位置,要求左上方处下边最少有连续的length个1,右边最少有连续的length个1 //[row + length - 1][col]代表左下角,要求该点右边最少有连续的length个1 //[row][col + length - 1]代表右上角,要求该点下边最少有连续的length个1 //这样便确立了四个边 if (right[row][col] >= length && down[row][col] >= length && right[row + length - 1][col] >= length && down[row][col + length - 1] >= length) { return true; } } } return false; } public static int[][] generateRandom01Matrix(int rowSize, int colSize) { int[][] res = new int[rowSize][colSize]; for (int i = 0; i != rowSize; i++) { for (int j = 0; j != colSize; j++) { res[i][j] = (int) (Math.random() * 2); } } return res; } public static void printMatrix(int[][] matrix) { for (int i = 0; i != matrix.length; i++) { for (int j = 0; j != matrix[0].length; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); } } public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int[][] arr=new int[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ arr[i][j]=sc.nextInt(); } } System.out.println(getMaxSize(arr)); } }
#include <bits/stdc++.h> using namespace std; int main(){ int n; scanf("%d", &n); vector<vector<int>> m(n, vector<int>(n)); for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ scanf("%d", &m[i][j]); } } int ans = 0; vector<vector<int>> dp(n+1, vector<int>(n+1, 0)); for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ if(m[i][j] == 1){ dp[i+1][j+1] = min(min(dp[i][j+1], dp[i+1][j]), dp[i][j]) + 1; ans = max(ans, dp[i+1][j+1]); } } } printf("%d", ans); return 0; }
#include<bits/stdc++.h> using namespace std; void setBorderMap(vector<vector<int>>& matrix,vector<vector<int>>& right,vector<vector<int>>& down) { int n = matrix.size(); for(int i=n-1;i>=0;--i) { for(int j=n-1;j>=0;--j) { if(i==n-1 && j==n-1) { right[i][j] = matrix[i][j] ? 1 : 0; down[i][j] = matrix[i][j] ? 1 : 0; } else if(i==n-1) { down[i][j] = matrix[i][j] ? 1 : 0; right[i][j] = matrix[i][j] ? right[i][j+1] + 1 : 0; } else if(j==n-1) { right[i][j] = matrix[i][j] ? 1 : 0; down[i][j] = matrix[i][j] ? down[i+1][j] + 1 : 0; } else { right[i][j] = matrix[i][j] ? right[i][j+1] + 1 : 0; down[i][j] = matrix[i][j] ? down[i+1][j] + 1 : 0; } } } } bool hasSizeOfBorder(int i,int j,vector<vector<int>>& right,vector<vector<int>>& down,int size) { int n = right.size(); if(n-i>=size && n-j>=size && right[i][j]>=size && down[i][j]>=size && right[i+size-1][j]>=size && down[i][j+size-1]>=size) return true; else return false; } int main() { int n; cin>>n; vector<vector<int>>matrix(n,vector<int>(n,0)); for(int i=0;i<n;++i) for(int j=0;j<n;++j) cin>>matrix[i][j]; vector<vector<int>>right(n,vector<int>(n,0)); vector<vector<int>>down(n,vector<int>(n,0)); setBorderMap(matrix,right,down); int ans = 0; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { for(int size = 1;size<=n;++size) { if(hasSizeOfBorder(i,j,right,down,size)) ans = max(ans,size); } } } cout<<ans; return 0; }