题目1 : Big Plus
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
Given an NxN 01 matrix, find the biggest plus (+) consisting of 1s in the matrix.
size 1 plus size 2 plus size 3 plus size 4 plus
1 1 1 1
111 1 1 1
1 11111 1 1
1 1111111 1
1 1 111111111
1 1
1 1
1
1
输入
The first line contains an integer N. (1 <= N <= 500)
Then follow an NxN 01 matrix.
输出
The size of the biggest plus in the matrix.
样例输入
5
00100
00100
11111
00110
10101
样例输出
2
解决本题需要使用一个经典的优化技巧:前缀和。
对于矩阵中每一个位置(i, j),我们可以计算up[i][j]
, down[i][j]
, left[i][j]
, right[i][j]
,一次是从(i, j)开始,向上下左右四个方向最多能延伸出多少连续的1。
如果A[i][j]=0
,则up[i][j]=down[i][j]=left[i][j]=right[i][j]=0
利用类似前缀和的技巧,否则有递推式:
up[i][j] = up[i - 1][j] + 1
down[i][j] = down[i + 1][j] + 1
left[i][j] = left[i][j - 1] + 1
right[i][j] = right[i][j + 1] + 1
我们可以先从上到下,从左到右计算出up[i][j]
和left[i][j]
,再反向计算出down[i][j]
和right[i][j]
。时间复杂度是O(N^2)
。
最后对于每个(i, j),up[i][j]
, down[i][j]
, left[i][j]
, right[i][j]
的最小值就是以(i, j)为中心的Plus的size。所有(i, j)的最大值就是答案。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Scanner scanner = new Scanner(input);
int N = scanner.nextInt();
// System.out.println("N:" + N);
char[][] matrix = new char[N][];
for (int i = 0; i < N; i++) {
matrix[i] = scanner.next().toCharArray();
}
// System.out.println(Arrays.deepToString(matrix));
int[][] left = new int[N][N];
int[][] right = new int[N][N];
int[][] up = new int[N][N];
int[][] down = new int[N][N];
// calculate left && up
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
if (matrix[row][col] == '0') {
left[row][col] = 0;
up[row][col] = 0;
} else {
left[row][col] = col > 0 ? left[row][col - 1] + 1 : 1;
up[row][col] = row > 0 ? up[row - 1][col] + 1 : 1;
}
}
}
// calculate right && down
for (int row = N - 1; row >= 0; row--) {
for (int col = N - 1; col >= 0; col--) {
if (matrix[row][col] == '0') {
right[row][col] = 0;
down[row][col] = 0;
} else {
right[row][col] = col < N - 1 ? right[row][col + 1] + 1 : 1;
down[row][col] = row < N - 1 ? down[row + 1][col] + 1 : 1;
}
}
}
int result = 0;
// traverse!
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
if (matrix[row][col] == '1') {
int size = min(left[row][col], right[row][col], up[row][col], down[row][col]);
// System.out.println("row:" + row + ", col:" + col + ", size:" + size);
result = Math.max(result, size - 1);
}
}
}
System.out.println(result);
}
static int min(int[] nums) {
int result = Integer.MAX_VALUE;
for (int num : nums) {
result = Math.min(result, num);
}
return result;
}
}