初めてのPBC
夕食を食べた後、自分の部屋に戻ってノートパソコンを出す。今夜はひまり先輩から教えてもらった競技プログラミングのコンテストに出てみようと思う。
初心者向けだって言ってたし、そんなに難しくないはず。
コンテストの名前、PBCだったっけ?あんまり自信ないけど、調べたら出てくるかな?
「PBC コンテスト」と検索。一番上に出てきたものがそれらしかった。
Programming Beginner Contest 028
コンテスト時間:60分(21:00~22:00)
レーティング更新対象:0~400
配点
A 100
B 100
C 150
D 200
E 250
F 300
初めて参加される方は、まずアカウントを作成してください。
このコンテストはインターネットでの検索や、書籍の参照を認めております。しかし、他人と相談しながらコンテストに参加することは禁止されています。
私は初めて参加する方なので、アカウントを作る。うっ、私ニックネームとか考えるの苦手なんだよね......思いつかないから本名でいいか。困ることがあったら後から変えよう。
確認。コンテストは21時から22時までの1時間。時間内に解いた問題の合計得点で順位が決まる。得点が同じ人同士は解いた時間が短かった方が良い順位になる。
そして、順位表はリアルタイムで見ることができるらしい。定期試験と違って、自分の答えが合っているかがコンテスト中に分かるのが斬新で面白いね。
始まるまであと3分はある。Pythonの本持ってきた方がいいかな。先輩方には競プロをする分には十分にプログラミングができるって太鼓判を押してもらったけど、この本まだ全然見てないページばっかりだし。
あ、プログラミングしないといけないから、コードエディタも開いとかないと。
気づいたらコンテストが始まるまであと30秒だった。そういえば、初めて参加する人はどのくらい解けるんだろう。一時間あるから、一問あたり20分くらいだと考えると、三問目までは解けるかな?ひまり先輩に聞いておけば良かった。
あと10秒。時計の秒針を見つめる。窓の外で夏の虫が鳴いているのがよく聞こえる。
壁掛け時計の秒針が真上を向く。私はA問題のページを開いた。
A - First Collatz
実行制限時間:2sec/メモリ制限:1024MB
配点:100点
<<問題文>>
1以上100以下の整数Nが与えられます。
Nが偶数の場合、Nを2で割った値を出力してください。
Nが奇数の場合、Nを3倍してから1を足した値を出力してください。
<制約>
入力はすべて整数である。
1 ≦ N ≦ 100
<入力形式>
N
<入力例1>
14
<出力例1>
7
7.0など、小数点以下が表示されていると正答と判定されないため注意してください。
<入力例2>
31
<出力例2>
94
良かった。昨日哀先輩が見せてくれたページと同じウェブサイトっぽい。問題を急いで読む。
まず、数字を受け取るんだね。数を受け取るから普通のinput()じゃだめで、n = int(input())と書かないと。
そのあとは、受け取った数が偶数、つまり2とか14とかみたいに「2×なんとか」と書ける数なら、その数を2で割ったものを出力する。
「もし~なら」だから、if文で書ける!
受け取った数が奇数の場合は、3倍してから1を足したものを出力する。
奇数は偶数じゃない方だから、偶数のときのif文の後ろにelseと書いておけば大丈夫。
よし、できる!私は急いでプログラムを書き始めた。
まだキーボードで入力するのに慣れてないから時間がかかる。=や()を入力するときにshiftキーも押さないといけないから大変。
キーボードで早く打つ練習もしないとね。先輩方みたいにタッチタイピングしたい。
<<Python>>
n = int(input())
if ...
......あれ、受け取った数が偶数かって、どうやって判定すればいいんだろう?
偶数の一の位は0,2,4,6,8しかないからそれを判定する?
うーん、それをちょっとプログラムでどうやって書けばいいかパッと思いつかない。
あ、受け取った数が2で割り切れるかどうか判定するのはどうだろう。偶数は必ず2で割り切れて、奇数は必ず2で割り切れないから。
えっと、2で割り切れるってことはどういうことだっけ?
2で割ったときの余りが0になる、と言い換えられるね。だから、割った余りを計算できれば良さそう。
プログラムで割った余りを計算するのってどうすればいいんだろう。足し算記号とか掛け算記号とかの(+, *)は教科書で見たけど、そんなのあったかな。
よく考えてみると、割り算の下にもう一個何か説明があったような気がしてきた。
うーん、なんだったかな?絶妙に覚えてないな。
......そういえば、教科書とかで調べてもいいルールだったね。素直に教科書を読みます。
ふむふむ。割った余りを求めるのは%でできるらしい。
つまり、nを2で割った余りを求めるには、n % 2 と書けばいい。これを使えば n % 2 が0と等しいときは偶数で、等しくないときは奇数と分かる!
プログラムで数が等しいか判定するのは普通にイコールでいいのかな?ちょうど教科書開いたし、ついでに調べておこう。
えっと。一致しているかの判定のときは、イコールを二つ使ってn % 2 == 0 みたいに書くといいんだね。
たしかに、イコール一つだと、変数を宣言する x = 2 とかと見分けがつかないよね。
<<Python>>
n = int(input())
if n % 2 == 0:
print(n / 2)
else:
print(n * 3 + 1)
よし、完成!。あとは入力例を試してみよう。
<<Terminal>>
>python main.py
>14
7.0
あれ、後ろの.0は要らないんだけど。割り算のときだけ小数点が出てくるんだっけ。
あ、整数にするには、int()で囲えば良かったね。さっきinput()でやったばっかりだ。
<<Python>>
n = int(input())
if n % 2 == 0:
print(int(n / 2))
else:
print(n * 3 + 1)
入力例を試すと、今度はちゃんと小数点なしで表示された。
プログラムはこれで完成かな。提出するには、書いたプログラムをコピペすると良さそう。言語をPythonにして、提出!
少しの間待つと、提出履歴に緑色でACと表示される。よし、正解!せっかくなので順位表も見てみよう。
︙
3750 pencil728 100点
3751 灰崎ゆい 100点
3752 wannkoromoti 100点
︙
3751位ってことは、自分が解くまでに3750人もこの問題を解いたってことか。急いで次の問題を解かないと。最初の問題から時間かかっちゃった。
......ちょっと待って、ユーザーネームを本名にしてるの私だけ?このコンテスト終わったら変えよう。恥ずかしい。
B - Dictionary Order
実行制限時間:2sec/メモリ制限:1024MB
配点:100点
<<問題文>>
英小文字からなる2つの文字列 S, T が与えられます。
文字列を辞書式順序で小さいものから順に、改行区切りで出力してください。
<制約>
S, T は英小文字からなる長さ1以上100以下の文字列
S, T は相異なる
<入力形式>
S
T
<入力例1>
program
accepted
<出力例1>
accepted
program
<入力例2>
person
present
<出力例2>
person
present
辞書式順序は、辞書で出てくる順番って字面から想像できるけど、文字列の辞書式順序で小さい方ってどっちだろう?
小さいって書いてあるくらいだから、文字列にも不等号が使えないかな?試しに書いてみよう。
<<Python>>
s = input()
t = input()
if(s > t):
print("SはTより大きい")
if(s < t):
print("SはTより小さい")
入力例1を試してみよう。programは文字列Sで、acceptedは文字列Tだね。
辞書だとacceptedの方が先に出てくるけど、どっちが小さくなるんだろう。
<<Terminal>>
>python main.py
>program
>accepted
SはTより大きい
えっと、これが表示されたということはどっちが小さいんだっけ?
出力された「SはTより大きい」を言い換えると、つまり accepted < program ってことだね。
だから、辞書式順序で小さい方というのは、辞書で先に出てくる方って意味っぽいね。
小さい文字列から表示されてほしいから、S > Tのときは文字列Tから表示されるようにすれば完成だね。
まあ、文字列に使える不等号が本当に辞書式順序なのかは分からないけど。
<<Python>>
s = input()
t = input()
if(s > t):
print(t)
print(s)
if(s < t):
print(s)
print(t)
コピペして提出してから、少し待つ。
結果が返ってくるまでの10秒くらいのこの時間めっちゃ緊張する。
緑色のACが表示された。よし、これで二問目まで解けた。
あ、でも辞書式順序はあんまり分かってないから後で調べないとね。三問目のページを開いた。
C - Missing Parentheses
実行制限時間:2sec/メモリ制限:1024MB
配点:150点
<<問題文>>
括弧 '(' , ')' と英小文字からなる、長さNの文字列 S が与えられます。
'(' と ')' の個数が一致しているときは、"true"、一致していないときは"false"と出力してください。
<制約>
2 ≦ N ≦ 10^5
S は'(', ')',英小文字からなる長さNの文字列
<入力形式>
N
S
<入力例1>
7
print(x
<出力例1>
false
<入力例2>
4
())(
<出力例2>
true
要は、文字列の中の括弧の数を数えて、左括弧と右括弧の個数が同じかどうか判定すれば良いんだよね。
文字列って配列みたいにs[0],s[1]ってやると、前から一番目の文字とか二番目の文字が確認できるのかな?
それができるなら、あとはfor文で最初の文字から括弧の個数を数えていけばいいね。
個数を数えるから、変数の名前はcounterとかにしとこうかな。左括弧を数える変数はcounter0にして、右括弧を数える変数はconuter1にした。
最後に、(の数と)の数が一致するかをif文で判定すれば完成。一致はさっき教科書で確認したようにイコール二つだね。
よし、この問題はそこまで詰まらずに考えられた。キーボードで打つのが遅いから、そこがもったいないんだけど。
<<Python>>
n = int(input())
s = input()
counter0 = 0
counter1 = 0
for i in range(n):
if s[i] == "(":
counter0 += 1
if s[i] == ")":
counter1 += 1
if counter0 == counter1:
print("true")
else:
print("false")
入力例を試して、良さそうなので提出。また結果が出るまでちょっと待つ。
ACと表示されたから、正解だ。これで三問目まで正解したことになる。初めて参加したにしては中々いいペースじゃないかなと我ながら思う。
そういえば、始まってからどのくらい時間が経ったんだろう。
ふと時計を見ると、ちょうど長針が8を指したところだった。え、もう40分経ったの!?コンテストが終わるまであと20分しかない。
今のペースなら、四問目を解くのがぎりぎり間に合うかも。ここまで来たら間に合わせたい。
プログラムを提出したときの結果は、
AC: 正解 (ACcepted)
WA: 不正解 (Wrong Answer)
RE: 実行時にエラーが出た (Runtime Error)
などのようにいくつか種類があります。
響きが良いですが、安易にAC!と言うと競技プログラミングをやっている人に絡まれるので注意した方が良さげです。




