ABC464 B - Crop
切り抜き
考え方
上下左右の余白を切り落とす問題。
入力例を見れば容易にわかるように、黒マスがある範囲を切り出して出力すればよい。
そのため、まず黒マスの存在範囲を調べる。
具体的には、すべての黒いマスの位置 $(i,j)$ について、以下を調べればよい。
- 左端:$j$ の最小値
- 右端:$j$ の最大値
- 上端:$i$ の最小値
- 下端:$i$ の最大値
最後に、$u$ 行目から $d$ 行目までについて、$l$ 列目から $r$ 列目までを切り出して出力すればよい。
これは、forループとかで $1$ 文字ずつ取り出すか、.substr() で $r-l+1$ 文字まとめて取り出す。
入力例1での動作
入力を受け取る。
h: 4
w: 5
s: {".....",
"..#..",
".###.",
"....."}
全てのマスを順に見て、黒いマスを見つけるたびに上下左右の端を更新する。
黒いマスの位置と、その時点での上下左右の端は次のようになる。
| 見つけた黒いマス | 左端 | 右端 | 上端 | 下端 |
|---|---|---|---|---|
| $(1,2)$ | $2$ | $2$ | $1$ | $1$ |
| $(2,1)$ | $1$ | $2$ | $1$ | $2$ |
| $(2,2)$ | $1$ | $2$ | $1$ | $2$ |
| $(2,3)$ | $1$ | $3$ | $1$ | $2$ |
最終的に、黒いマスが存在する範囲は、上端が $1$、下端が $2$、左端が $1$、右端が $3$ となる。
この範囲を各行から切り出す。
| 行 | 元の文字列 | 切り出す部分 |
|---|---|---|
| $1$ | "..#.." |
".#." |
| $2$ | ".###." |
"###" |
したがって、出力は次のようになる。
.#.
###
注意点
特になし。
別解
特になし。