見出し画像

[ABC278 Python]AtCoder Beginner Contest 278A~C問題Python解説

ABC278の解説記事です。
ご質問等ございましたらコメントにてお知らせください。
最後におまけとしてD問題もありますので、是非ご覧ください。

A問題

N, K = map(int, input().split())
A = list(map(int, input().split()))
K = min(N, K)
print(*A[K:]+[0]*K)

Nの制約が少ないので、ループで問題文通り解いても大丈夫ですが、少し工夫するだけで簡単に解くことができます。

まず、Aの先頭の要素をK回取り除くので、
表示するリストはA[K:]となります。
そしてAの末尾に0をK回挿入するので、
[0]*Kをリストの末尾に追加します。

ただ、入力例2より、
N<Kの場合は、K = Nとなるみたいなので、
NとKの大きいほうが、Kとなることに注意しましょう。


B問題

H, M = map(int, input().split())
while True:
    if H//10*10+M//10 < 24 and H%10*10+M%10<60:
        print(H, M)
        break
    else:
        if M == 59:
            if H == 23:
                H = 0
                M = 0
            else:
                H += 1
                M = 0
        else:
            M += 1

noteの仕様によりコードが一部見にくくなっていますがご了承ください。

どんなに時間がかかったとしても、23*60回ループすれば見間違えやすい時刻に到達するので、全探索するのがいいでしょう。

whileループを使って、
H時M分から1分ずつ進めることで、
初めて見間違えやすい時刻に到達したら出力して終了します。

まずは見間違えやすい時刻の判定作業を行います。
問題文からHの1の位とMの10の位を入れ替えるので、
H//10とM%10、H%10とM//10をそれぞれ入れ替えて、
”時”の方は24より小さいか、“分“の方は60より小さいかを確認し、
見間違えやすい時刻かどうか判定します。
判定がTrueだった場合はその時刻を出力してプログラムを終了します。

もし判定がFalseだったら時刻を1分進めるフェーズに入ります。
ただ、M+1をすればいいかというとそうではなく、
例えばM=59の時M+=1してM=60となってしまったら、
時計として成り立っていないので、条件によって制御する必要があります。

まず、H=23、M=59の場合は1分後が0時0分になるので、
H=0、M=0となります。
また、H<23、M=59の場合は、1分後にH+1時0分になるので、
H=H+1、M=0となります。
以上の条件以外の場合は、Hは変化せずM=M+1として次に進みます。


C問題

N, Q = map(int, input().split())
d = {}
from collections import defaultdict
d = defaultdict(int)

for i in range(Q):
    T, A, B = input().split()
    A = A.zfill(10)
    B = B.zfill(10)
    if T == "1":
        d[A+B] = 1
    elif T == "2":
        d[A+B] = 0
    else:
        if d[A+B] == 1 and d[B+A] == 1:
            print("Yes")
        else:
            print("No")

単純に二重リスト等でサービスを保存すると、
TLEになってしまうので、工夫する必要があります。

まずは、AとBは整数で与えられるので、
A+Bで指定してしまうとA→BとB→Aの区別をすることができません。
そこで、AとBを文字列として受けとると、
A+BとB+Aは別な値(A=1,B=2の場合はA+B=12、B+A=21)
になります。
これを使うことで、ABの場合はAがBをフォローしているか、を表すことになります。

次にdefaultdictでフォローの有無を指定します。
defaultdictは以下をご覧ください。

初期値は全て0になる(全員フォローなし)ので、
d[AB]=0ならばAはBをフォローしていない、
d[AB]=1ならばAはBをフォローしているとなります。

ですので、
T=1の時は、d[AB]=1として
T=2の時は、d[AB]=0とします。

T=3の時はd[AB]=1とd[BA]=1の両方を満たすか確認し、
両方満たすときはYes、満たさない場合はNoを出力します。

最後に一つ注意ですが、
例えばA=11、B=1の時にはABとBAがともに111になってしまうので、
AとBの最大値10^9ですので、10^10まで0埋めする
(A=11ならA=0000000011)ことで、
全てのキーに違いを出すことができます。



おまけ:D問題

from collections import defaultdict

N = int(input())
A = list(map(int, input().split()))
Q = int(input())
d = defaultdict(int)

for i in range(N):
    d[i] = A[i]

x = 0
for i in range(Q):
    que = list(map(int, input().split()))
    if que[0] == 1:
        x = que[1]
        d = defaultdict(int)
    elif que[0] == 2:
        d[que[1]-1] += que[2]
    else:
        print(x + d[que[1]-1])

ざっくりとした解説

クエリ1の時、全ての要素がXに変更されますので、
一括でxに代入します。
クエリ2の時、変化するのはAiだけですので、
defaultdictでその分足しておきます。
クエリ3の時、クエリ1で変更されたXとクエリ2の変化した分を足して出力します。

またクエリ1の時、これまでのdefaultdictは必要ないので、
初期化することを忘れずに。

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