Big Plus

题目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;
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_38970751/article/details/85337608
今日推荐