いがメモ

プログラミング関連についてやったことの記録を書いていきます。

TopCoder SRM 610 Div1 Easy TheMatrix [1人競技プログラミング Advent Calendar 2016 10日目]

昨日寝落ちしながら解法を生み出していた。

この記事は1人競技プログラミング Advent Calendar 2016 10日目の記事です。

問題概要:
TopCoder Statistics - Problem Statement
白と黒のマスのグリッドが与えられる。
任意の四角形のグリッドを切り抜くことが出来る。
切り抜いた際に四角形のグリッドの全てのマスが「隣接マスが自身のマスと違う色である」という条件を満たしている必要がある。
上記の条件を満たした上で、最も大きく切り抜けるマスの数の個数を答えよ。

解いた方法:
下から累積和して
memo[i][j] = j列目のi行目のマスからスタートした際に、j列で取れるマスの個数
を保持しておく。

全てのマスからスタートし、列を増やすごとに作る事の出来る四角形の最大サイズをほぼO(1)で計算することが出来るようになる。

#include<bits/stdc++.h>

#define MP make_pair
#define PB push_back
#define ALL(x) (x).begin(),(x).end()
#define REP(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<(n);i++)
#define REP2(i,d,n) for(int i=(d);i<(n);i++)
#define RREP(i,n) for(int i=(n);i>=0;i--)
#define CLR(a)      memset((a),0,sizeof(a))
#define MCLR(a)     memset((a),-1,sizeof(a))
#define RANGE(x,y,maxX,maxY) (0 <= (x) && 0 <= (y) && (x) < (maxX) && (y) < (maxY))

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<LL> VLL;
typedef pair<int,int> PII;

const int INF = 0x3f3f3f3f;
const LL INFL = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-9;

const int DX[]={1,0,-1,0},DY[]={0,-1,0,1};

int memo[101][101];

class TheMatrix {
    public:
    vector<string> board;
    int MaxArea(vector<string> _board) {
        board = _board;
        REP(i, 101) REP(j, 101) memo[i][j] = 0;

        REP(i, board[0].length()){
            memo[board.size()-1][i] = 1;
        }

        for(int i=(int)board.size()-2; i>=0; i--){
            REP(j, board[0].length()){
                if(board[i+1][j] == board[i][j]) memo[i][j] = 1;
                else memo[i][j] = memo[i+1][j] + 1;
            }
        }

        int ans = 0;
        REP(i, board.size()){
            REP(j, board[0].length()){
                int min_cnt = memo[i][j];
                REP2(k, j, board[0].length()){
                    if(k != j && board[i][k-1] == board[i][k]) break;
                    min_cnt = min(min_cnt, memo[i][k]);
                    ans = max(ans, min_cnt * (k-j+1));
                }
            }
        }


        return ans;
    }
};