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さん主催、協賛のコンテストで毎回レート下がっていると冒頭に書きましたが、今回もレート下がりました。
・・・悲しい。
コメント