DPL_3_A 最大正方形

Calendar Clock iconCalendar Clock icon

AOJ

目次

# 問題

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_A

# 解説

タイルを表現する行列と同じサイズの行列をもう一つ用意する.
タイルを左上から順に見ていき、その時点での最大の辺の長さを以下のルールで記録していく.

  1. 一番上か一番左のタイルなら、汚れていたら0、きれいなら1
  2. その他のタイルで、自身が汚れていたら0
  3. その他のタイルで、自身がきれいなら、自身の左、左上、上の3つの値のうち最小のものに1を加えた値

タイルを降るたびに最大値を更新していき、最終的な最大値が最大編の長さなので2乗すれば面積になる.

# 計算量

O(N2)O(N^2)

# 解答

// C++ 14
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <math.h>

#define ll long long
#define Int int
#define loop(x, start, end) for(Int x = start; x < end; x++)
#define loopdown(x, start, end) for(int x = start; x > end; x--)
#define rep(n) for(int x = 0; x < n; x++)
#define span(a,x,y) a.begin()+x,a.begin()+y
#define span_all(a) a.begin(),a.end()
#define len(x) (x.size())
#define last(x) (*(x.end()-1))

using namespace std;
#define MAX_N 1401

Int H, W;
bool S[MAX_N][MAX_N];
Int A[MAX_N][MAX_N];

void input() {
  cin >> H >> W;
  loop(h,0,H) {
    loop(w,0,W) {
      cin >> S[h][w];
      A[h][w] = -1;
    }
  }
}

void solve() {
  Int max_ = 0;
  loop(h,0,H) {
    A[h][0] = (S[h][0]) ? 0 : 1;
    max_ |= A[h][0];
  }
  loop(w,0,W) {
    A[0][w] = (S[0][w]) ? 0 : 1;
    max_ |= A[0][w];
  }

  loop(h,1,H) {
    loop(w,1,W) {
      if (S[h][w]) {
        A[h][w] = 0;
        continue;
      }

      A[h][w] = min(A[h-1][w], min(A[h][w-1], A[h-1][w-1])) + 1;
      if (A[h][w] > max_) max_ = A[h][w];
    }
  }

  cout << max_*max_ << endl;
}

int main(void) {
  input();
  solve();
}

リモートフリーランス。ウェブサービス、スマホアプリエンジニア。
東アジアを拠点に世界を移動しながら活動してます!

お仕事のご依頼・お問い合わせはこちら

コメント