はまやんはまやんはまやん

hamayanhamayan's blog

Grid Compression [AtCoder Beginner Contest 107 B]

https://beta.atcoder.jp/contests/abc107/tasks/abc107_b

解法

https://beta.atcoder.jp/contests/abc107/submissions/3080988

操作ができなくなるまで操作をするが、whileの中に処理用の関数を入れて実装した。
check() := 操作を行って、操作が行えれば1, 操作が行えなければ0を返す
1が帰ってくればwhileが継続されるので、操作を継続してくれる。
 
消す操作の実装が少し困る所。
行を消す場合は、消したい行をswapで順番に移動させて最後に持ってくる。
そしてH--をすると、指定の行だけ消すことができる。
列を消す場合は全ての行についてA[yy] = A[yy].substr(0, x) + A[yy].substr(x + 1);をすると消せる。
stringのsubstrの良いところは空文字列の場合でもうまくやってくれる所。

int H, W;
string A[101];
//---------------------------------------------------------------------------------------------------
int check() {
    rep(y, 0, H) {
        int ok = 1;
        rep(x, 0, W) if (A[y][x] == '#') ok = 0;
        if (ok) {
            rep(yy, y + 1, H) swap(A[yy - 1], A[yy]);
            H--;
            return 1;
        }
    }
 
    rep(x, 0, W) {
        int ok = 1;
        rep(y, 0, H) if (A[y][x] == '#') ok = 0;
        if (ok) {
            rep(yy, 0, H) A[yy] = A[yy].substr(0, x) + A[yy].substr(x + 1);
            W--;
            return 1;
        }
    }
 
    return 0;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> H >> W;
    rep(y, 0, H) cin >> A[y];
    while (check());
    rep(y, 0, H) cout << A[y] << endl;
}