C - Connect 6 Editorial by Nyaan


(これはユーザー解説です)

この問題は面倒な処理を上手に実装できるかがテーマとなっている問題です。
問題文に実直に実装すると \(4\) 方向 あるいは \(8\) 方向への探索を実装することになり、少し面倒なことになってしまいます。

  • 実際、コンテスト中は実装が 100 行を超えてしまいデバッグに苦労した、という方も少なくなかったようです。

実装の量を減らす方法として、同じ処理を共通する関数で処理する という方針があるので簡単に紹介します。

まず、\((x,y), (x+dx,y+dy), \dots, (x + 5 \times dx, y + 5 \times dy)\) を調べて、問題の条件を満たす時に True を返す関数を書いてみましょう。

# (x,y) を始点として (dx,dy) 方向を調べる
# 問題の条件を満たす列が見つかれば True
def calc(x, y, dx, dy):
  count = 0
  for i in range(6):
    if not (0 <= min(x, y) and max(x, y) < N):
      # マス目からはみ出したら失敗
      return False
    if S[x][y] == '#':
      count += 1
    x += dx
    y += dy
  # 4 個以上黒で塗られていれば True
  return count >= 4

そして、これを for 文で回しましょう。

N = int(input())
S = [input()for _ in range(N)]

Dx = [1, 0, 1, 1]
Dy = [0, 1, 1, -1]
for x in range(N):
  for y in range(N):
    for dx, dy in zip(Dx, Dy):
      if calc(x, y, dx, dy):
        print("Yes")
        exit()
print("No")

なんとこれだけで完成です。提出

このように処理を共通化することで、似たような処理を何度も何度も書く必要が無くなり、デバッグも楽になります。

実装が苦手な方やデバッグで詰まった方は、こうした方針をスムーズに選べるようになると実装の苦労が減ると思います。ぜひお試しください。

posted:
last update: