競プロ弱者の解答

競プロ弱者の成長記録

ABC101(バーチャル):水色競プロerの復習

これまで、ABCの100からだんだん過去の問題に遡って復習してきたのですが、
これでは最近の問題にたどりつかないことに気づき、方針変更。
これからはだんだん新しい問題に進むことにします。
というわけで今回はABC101にチャレンジしました。

〇コンテスト名:ABC101

〇配点:不明

〇制限時間100分(A~Dまでの4問の時代のコンテスト)

〇今回の方針
 3/1にABCが生えることを祈りながら、実戦のつもりで行きましょう。

コンテスト開始!
A - Eating Symbols Easy

  1. と-でできた4文字が与えらえる。

最初は0で、+が出たら+1、-がでたらー1。
いくつになるか?

すぐ思いつく方針は下の2つでしょうか。
①countで+の数を数える。
②+が出たら1を足し、そうでなければ(-が出たら)1を引く。

どちらでもよいのですが、②を選択しました。

S=input()
ans=0
for i in range(4):
    if S[i]=="+":
        ans+=1
    else:
        ans-=1
print(ans)

1:36 AC

B - Digit Sums
整数Nが与えらえる。
Nの各桁の和をnとする。
Nはnで割り切れるか?

この手の問題はintとstrの変換を思いつけば難易度がぐっと下がります。
問題文の通りに実装しましょう。

N=int(input())
SN=str(N)
sn=0
for i in range(len(SN)):
    sn+=int(SN[i])
if N%sn==0:
    print("Yes")
else:
    print("No")

4:21 AC

C - Minimization
1からNを並べ替えた数列がある。
連続するK個をその中の最小値にする操作を行う。
すべて同じ数にするために必要な操作の回数の最小値を求めよ。

どう考えても、最後はすべて1になるはず。
そして、左端を1にする最善手は下の図のようになるはずで、結局左端からK-1を足していくのと同じことになりますね。
f:id:syunsuk1024:20200228223127p:plain

そのまま右端まで1になるようにするには・・・
あれ?数列Aはいらない?

import math
N,K=map(int,input().split())
print(math.ceil((N-1)/(K-1)))

8:33 AC

D - Snuke Numbers

整数NをNの各桁の数字を足した数S(N)で割り、N

K=int(input())
D={}
for i in range(1,10**4):
    for j in range(12):
        Sunuke=str(i)+("9"*j)
        if len(Sunuke)<=15 and Sunuke not in D:
            S=0
            for k in range(len(Sunuke)):
                S+=int(Sunuke[k])
            D[int(Sunuke)]=S
D=list(D.items())
D.sort()

import bisect

d=[10**16 for i in range(len(D))]
d[0]=0
ans=[0 for i in range(len(D))]
for i in range(len(D)):
    ans[bisect.bisect_right(d,D[i][0]/D[i][1])]=D[i][0]
    d[bisect.bisect_right(d,D[i][0]/D[i][1])]=D[i][0]/D[i][1]
    
ANS=[]
MAX=0
for i in range(len(ans)):
    if ans[i]>MAX:
        ANS.append(ans[i])
        MAX=ans[i]

for i in range(K):
    print(ANS[i])

29:29 AC

実験って大切ですね。
今回はプレッシャーのかからない状態だったので実験ができましたが、
いつかコンテスト中のギリギリの状態で実験から答えを導き出してみたいものですね。

結局29:29で全完(4完)ノーペナ
すばらしい結果でした。