ABC203参戦記

プログラミング

AHC003が終わって1時間後に開始となったABC203に参加しました。
Panasonicさん協賛のコンテストです。Panasonicさん、ありがとうございます。
家電はPanasonicさんの製品を多く利用しています。この記事もLetsNoteで書いています。少額ではありますが、株主です。
ちなみに、今までPanasonicさん主催、協賛のコンテストでは、全てレートを落としています・・・
許すまじ。

そんなPanasonicさんに複雑な感情を抱いている私が今回のABC203のAからCまでで考えたこと、AC↓コードを書いていきます。
使用言語はPython3です。レートは茶色中位くらいです。

A – Chinchirorin

場合分けと条件判定が書けるかを問われる問題。

a,b,c の3つのサイコロで同じ組があるかどうかを判定するには、aとb、bとc、cとa をチェックすればOKですね。3つすべてが同じ場合でも、どれかに引っ掛かります。これらのif文を書いていって、全てのif文に引っかからなければ 0 を出力すればOKですね。

a,b,c=map(int,input().split())
if a==b:
    print(c)
elif a==c:
    print(b)
elif b==c:
    print(a)
else:
    print(0)

if文は、if, elif, else を使うのが一般的だとは思いますが、if だけで判定していく際には、exit() しないと後続のプログラムが実行されてしまうため、WAになります。

# AtCoder Beginner Contest 203(Sponsored by Panasonic)
# A - Chinchirorin

a,b,c=map(int,input().split())

if a==b:
    print(c)
    exit()
if a==c:
    print(b)
    exit()
if b==c:
    print(a)
    exit()

print(0)

B – AtCoder Condominium

繰り返し処理が書けるか、また、3桁の数を数値として扱えるかが問われる問題。

問題に書かれている3桁の整数の i0j は、100*i + j とすればOKですね。

あとは、二重のfor文を書けば良いですが、1スタートなのと、Kを含む数までがfor文の範囲であることには注意が必要です。

# AtCoder Beginner Contest 203(Sponsored by Panasonic)
# B - AtCoder Condominium

N,K=map(int,input().split())

ans=0
for i in range (1,N+1):
    for j in range(1,K+1):
        ans+=100*i+j

print(ans)

勿論、次のコードのように、文字列としての i0j を、int( ioj ) としても、AC可能ですが、数を数として扱える方法を知っておいたほうが良いと思います。
元の数に10をかけて、1桁の整数を足すなども頻出ですね。

N,K=map(int,input().split())

ans=0
for i in range (1,N+1):
    for j in range(1,K+1):
        ans+=int(str(i)+"0"+str(j))

print(ans)

ちなみに、for文書かない、単純計算でも解けます。

N,K=map(int,input().split())
print(((N*(N+1))//2)*100*K + ((K*(K+1))//2)*N)

C – Friends and Travel costs

制約が緩いほうを選択してシミュレーションできるかが問われる問題。

今回の問題は、移動した村に友達がいるか。で判定してとくと、村の数だけ調べる必要があるので、TLEします。友達の数は、村よりもすくないため、友達を距離順でソートして、友達に会えるまで移動できるか。という問題として解いていきます。

上記の条件判定で、友達に会えるなら、所持金、現在地をそれぞれ更新していき、友達全員にあった後は、最後にあった村から、進める距離を出力しればOKです。

# AtCoder Beginner Contest 203(Sponsored by Panasonic)
# C - Friends and Travel costs

N,K=map(int,input().split())
ls=[]
for i in range(N):
    A,B=map(int,input().split())
    ls.append([A,B])

ls.sort()
now=0   # 現在地

for i in range(N):
    # 現在地から、K円で進める距離に友達がいるかを判定
    if now+K>=ls[i][0]:
        # 進んだ分だけ所持金をマイナス
        K-=ls[i][0]-now
        # 現在地を更新
        now=ls[i][0]
        # 友達から受け取ったお金をプラス
        K+=ls[i][1]
    
    # 友達がいなければ、現在地から進めるだけの距離を出力してexit()
    else:
        print(now+K)
        exit()

print(now+K)

所持金と現在地の更新、ここの値の更新順番を間違うとWAになります。
私は、コンテスト中、一つの村に複数の友達がいるケースでうまいこと行きませんでした。
考えた結果、一つの村からは、一人から全員分をまとめたお金を受け取るようにしました。
dict[ i ] がi 番目の村で受け取れるお金の総額です。これを保持しておいて、keyでソートしました。

# AtCoder Beginner Contest 203(Sponsored by Panasonic)
# C - Friends and Travel costs

N,K=map(int,input().split())

dic=dict()
s=set()
for i in range(N):
    A,B=map(int,input().split())
    # 村Aに友達がいたかを判定
    if A in s:
        a=dic[A]
        dic[A]=a+B
    else:
        dic[A]=B
    s.add(A)

# 村の順番にソート
sorted_dicls=sorted(dic.items(), key=lambda x:x[0])

now=0   # 現在地

# 村の数だけforloop
for i in range (len(s)):
    x=sorted_dicls[i][0]
    if now+K>=x:
        K-=x
        now+=x
        K+=sorted_dicls[i][1]
    else:
        print(now+K)
        exit()

print(now+K)

今、見返すと、現在地の変数 now の更新がよろしくなかったようですね。

ちなみに、Panasonicさん主催、協賛のコンテストで毎回レート下がっていると冒頭に書きましたが、今回もレート下がりました。
・・・悲しい。

コメント

タイトルとURLをコピーしました