Official

B - モザイクアートの作成 / Creating Mosaic Art Editorial by admin

GPT 5.2 High

概要

与えられた \(H \times W\)# / . からなる原案を、縦横それぞれ \(K\) 倍に拡大しつつ、#\(c_1\).\(c_2\) に置き換えた \(HK \times WK\) の文字列を出力します。

考察

ポイントは「各マスを \(K \times K\) の同じ文字のブロックにする」ことです。
これを素直に 2 次元配列(\(HK \times WK\))を用意して 1 マスずつ埋めても解けますが、わざわざ大きな配列を作る必要はありません。

観察すると、拡大後の各行は次の手順で作れます:

  • 原案の 1 行(長さ \(W\))を左から見て、
    • # なら文字 \(c_1\)\(K\) 回繰り返す
    • . なら文字 \(c_2\)\(K\) 回繰り返す
  • こうしてできた「拡大後の 1 行(長さ \(WK\))」を、縦方向にも \(K\) 回繰り返す

例えば \(K=3\) のとき、原案の1文字 # は横に c1c1c1、縦にも同じ行を3回出すことで \(3 \times 3\) ブロックになります。

素朴に「1 文字ずつ += で文字列を連結」すると、言語や書き方によっては連結が重くなりやすいですが、Python ではリストに断片を貯めて最後に ''.join(...) するのが定石です(本コードもこの形です)。

アルゴリズム

  1. 入力で \(H, W, K, c_1, c_2\) と原案の各行 \(S_i\) を受け取る。
  2. 各行 \(S_i\) について以下を行う:
    1. 各文字 ch を見て、# なら c1*K. なら c2*K を作り、順に連結して拡大後の1行 line(長さ \(WK\))を作る。
    2. その line を縦方向の拡大として \(K\) 回出力に追加する。
  3. 最後にすべての行を改行区切りで出力する。

計算量

  • 時間計算量: \(O(H \cdot W \cdot K)\)
    (最終的に出力する文字数が \(HK \cdot WK = H W K^2\) ですが、実装上は各マスにつき長さ \(K\) の文字列を作るため、文字生成量としては最終出力に比例します)
  • 空間計算量: \(O(H \cdot W \cdot K^2)\)(出力全体を out_lines に保持するため)
    ※逐次 print すれば保持せずに \(O(WK)\) 程度にもできます。

実装のポイント

  • 横方向の拡大は「tile * K」で一気に作ると簡単です(例:'a'*3 -> 'aaa')。

  • 文字列の連結は、断片をリストに入れて最後に ''.join(...) すると効率的です。

  • 縦方向の拡大は、作った 1 行を K 回繰り返して出力に追加するだけで実現できます(out_lines.extend([line] * K))。

    ソースコード

import sys

def main():
    it = iter(sys.stdin.read().split())
    H = int(next(it))
    W = int(next(it))
    K = int(next(it))
    c1 = next(it)
    c2 = next(it)

    out_lines = []
    for _ in range(H):
        s = next(it)
        expanded = []
        for ch in s:
            tile = c1 if ch == '#' else c2
            expanded.append(tile * K)
        line = ''.join(expanded)
        out_lines.extend([line] * K)

    sys.stdout.write("\n".join(out_lines))

if __name__ == "__main__":
    main()

この解説は gpt-5.2-high によって生成されました。

posted:
last update: