見出し画像

[ABC300 Python]ユニークビジョンプログラミングコンテスト2023 春 (AtCoder Beginner Contest 300)A~D問題Python解説

A問題

# 入力
N, A, B = map(int, input().split())
C = list(map(int, input().split()))
# 選択肢があっていれば、選択肢の番号を出力する。
for i in range(N):
    if C[i] == A+B:
        print(i+1)

選択肢を順番に見ていき、A+Bと一致すれば選択肢の番号を出力する。

B問題

# 入力
H, W = map(int, input().split())
A = [list(input()) for _ in range(H)]
B = [list(input()) for _ in range(H)]
# "#"の場所を保存する
# Aの"#"の場所
sharp_A = []
# Bの"#"の場所
sharp_B = []
for i in range(H):
    for j in range(W):
        if A[i][j] == "#":
            sharp_A.append([i, j])
        if B[i][j] == "#":
            sharp_B.append([i, j])
# Bの"#"の場所を昇順に並べ替える
sharp_B.sort()
# Aの"#"の場所が移動できる全ての箇所を調べる
for i in range(H):
    for j in range(W):
        # 移動後のAの"#"の場所
        moved_A = []
        for k in sharp_A:
            moved_A.append([(k[0]+i)%H, (k[1]+j)%W])
        # Aの"#"の場所を昇順に並べ替える
        moved_A.sort()
        # 並べ替えたのち、AとBの"#"の場所が一致したらYesと出力する
        if moved_A == sharp_B:
            print("Yes")
            exit()
print("No")

マス目の中から"#"のマスの座標を保存し、Aの"#"のマスの縦方向のシフトと横方向のシフトの全てのパターンを列挙する。
その中にBの"#"のマスと一致する組み合わせが存在すればYes、しなければNoと出力する。

C問題

# 入力
H, W = map(int, input().split())
C = [list(input()) for _ in range(H)]
# サイズnのバツ印の個数(0も含む)
ans = [0 for _ in range(min(H, W)+1)]
# 全てのマスを調べる
for i in range(H):
    for j in range(W):
        # あるマスが、"#"だとしたら、
        if C[i][j] == "#":
            # バツ印をカウントしたかどうかを判定するjudge
            judge = False
            # バツ印の斜めの個数
            c = 0
            # マス目の範囲を超えるまで
            while i+c < H and j+c < W:
                # マス目が"."であれば、
                if C[i+c][j+c] == ".":
                    # ansにサイズを保存
                    ans[c//2] += 1
                    # カウントしたのでTrueにする
                    judge = True
                    break
                else:
                    # マス目を"."にする
                    C[i+c][j+c] = "."
                    # そのまま続ける
                    c += 1
            # カウントしていなければ、ここでカウントする
            if not judge:
                ans[c//2] += 1
# バツ印にはサイズ0はないので、サイズ1から空白区切りで出力する
print(*ans[1:])

バツ印の中の右下がりの線を探す。
バツ印の中には右下がりの線は1つしかなく、その線はほかのバツ印の線とは交錯しないため、右下がりの線の数やサイズをカウントするだけで、バツ印の数やサイズをカウントすることができる。

マス目を右下がりに見ていき(x+=1,y+=1)、
"#"が続くところまで、カウントする。
"#"が止まれば、バツ印のサイズを答えのリストに加え、
これまでの"#"を全て"."に変えることで、2回以上数えることを防ぐことができる。

D問題


後日記載します。

この記事が気に入ったらサポートをしてみませんか?