🔤

ABC386の振り返り(Python)

2024/12/29に公開

ABC386の振り返り(Python)

ABC386に参加した結果の振り返りと学んだこと、今後の課題の備忘録
使用言語はPythonです

提出結果

A

https://atcoder.jp/contests/abc386/tasks/abc386_a

カードの文字の組み合わせは以下のようになる

  • 1, 1, 1, 1
  • 2, 1, 1
  • 2, 2
  • 3, 1
  • 4

(2, 2)、(3, 1)のときのみフルハウスができるので、辞書に登録して長さをはかればおっけー

abcd = list(map(int, input().split()))
abcd_dict = {}
for n in abcd:
    if n in abcd_dict:
        abcd_dict[n] += 1
    else:
        abcd_dict[n] = 1

if len(abcd_dict) == 2:
    print('Yes')
else:
    print('No')

B

https://atcoder.jp/contests/abc386/tasks/abc386_b

今見てる数字が0のときの条件分岐がめんどくさい

00...: 次の文字を飛ばす
0?...: ボタンを押して次に進む
0: ボタンを押して終了

急ぐあまりむしろ時間がかかってしまっていたので気を付けたいです...

n = list(input())
n_len = len(n)

index = 0
ans = 0
while(index < n_len):
    ans += 1

    # 00のとき以外は次に進む
    if n[index] != '0':
        index += 1
        continue
    if index == n_len - 1:
        break
    if n[index + 1] != '0':
        index += 1
        continue

    index += 2

print(ans)

C

https://atcoder.jp/contests/abc386/tasks/abc386_c

以下の方針で解こうとしたら実装がややこしいことに...
sとtの長さが2以上離れている場合を最初にはじいたうえで、
長さが同じ場合: 変更
sのほうが長い場合: 削除
sのほうが短い場合: 挿入
という操作が2回以上行われるならng

toamさんのユーザー解説がわかりやすく、かつ応用もききそうなので覚えておきたいです

k = int(input())
s = list(input())
t = list(input())
len_s = len(s)
len_t = len(t)

def change(s, index):
    if len_s == len_t:
        s[index] = t[index]
    elif len_s > len_t:
        s.pop(index)
    else:
        s.insert(index, t[index])
    return s

if len_s > len_t + 1 or len_s < len_t - 1:
    print('No')
else:
    ans = 'Yes'
    changed = False
    for i in range(len_t):
        if i == len_t - 1:
            if not changed:
                break
        if s[i] == t[i]:
            continue
        elif changed:
            ans = 'No'
            break
        else:
            changed = True
            s = change(s, i)
    print(ans)

D

https://atcoder.jp/contests/abc386/tasks/abc386_d

それぞれの黒が、すべての白の領域と被らないようにする、という愚直な解法でTLEで、そのままタイムアップ...
白の保存方法を工夫しておけばどうにか計算量を抑えられないかなとずっと考えていたのですが、何も思い浮かばなかったです。もしその方針で解ける解法があれば教えていただきたいです。

n, m = map(int, input().split())

black = []
white = []

for i in range(m):
    x, y, c = input().split()
    tmp = [int(x), int(y)]
    if c == 'B':
        black.append(tmp)
    else:
        white.append(tmp)

def check_white(x, y):
    global white
    for point in white:
        if x < point[0] or y < point[1]:
            continue
        else:
            return False
    return True

ans = 'Yes'
for i in range(len(black)):
    if not check_white(black[i][0], black[i][1]):
        ans = 'No'
        break
print(ans)

解説を読んでもよくわからなかったのですが、こちらがとても助かりました🙏

https://x.com/kyopro_friends/status/1873002635173011951

解説のコード+コメント

N, M = map(int, input().split())
xyc = []
for i in range(M):
    x, y, c = input().split()
    xyc.append((int(x), int(y), c))

# x, yの小さい順にみていく
# 先にソートしておくことで、その時のmin_yと比較するだけでいい
xyc.sort()

# すべて黒で埋める
min_y = 1 << 30

ans = "Yes"
for x, y, c in xyc:
    # min_yを記録しながら見ていく
    if c == "W":
        min_y = min(min_y, y)
    else:
        if y >= min_y:
            ans = "No"
print(ans)

反省点

急ぐあまり適当なコードを提出してしまっていた
最初の方針にとらわれてほかの解法を考えられなかった

感想

今回-18で入緑まであと77!

Discussion