paizaの森練習問題コンテストは、「paizaの森 (Discord)」にて約2か月に1回のペースで開催されており、ユーザー同士が開催時刻にpaizaの森に集まり「よーいドン」で与えられた数問の練習問題をお好きなプログラミング言語で解答する早さを競います。
(第2回練習問題コンテストは、D級3問 C級1問。)
それほど難しい問題は出題されないですし、誤答によるペナルティーもありませんので初心者でも気軽に参加出来ます。
また、コンテストから数日後には出題された問題が一般公開され、だれでも挑戦できるようになります。
本記事で使用しているメソッド・アルゴリズムについて
解答例で使っているメソッドやアルゴリズムについて、下記の記事で詳しく解説していますので参考にしてみて下さい。
- [Ruby] 標準入力によるデータ取得1
- [Ruby] 標準入力によるデータ取得2
- [Ruby] 標準入力によるデータ取得3
- [Ruby] 標準出力(データを任意に整形して出力する)
- [Ruby]配列の基本操作1
- [Ruby]繰り返し処理
- [Ruby]条件分岐
第2回 paizaの森練習問題コンテスト
1問目: 競輪のユニフォーム (paizaランク D 相当)
1~9のそれぞれに色が割り当てられていて、標準入力から番号 n
が与えられたときに、その番号に対応した色を出力する問題です。
【番号と色の対応】
- 1: white
- 2: black
- 3: red
- 4: blue
- 5: yellow
- 6: green
- 7: orange
- 8: pink
- 9: purple
入出力例
番号n
が与えられ、色を出力します。(例:2 が入力されたら、 black を出力する。)
INPUT1 = <<"EOS" 2 EOS OUTPUT1 = <<"EOS" black EOS INPUT2 = <<"EOS" 5 EOS OUTPUT2 = <<"EOS" yellow EOS
Ruby 解答例1
if文を使って、1から9までの条件分岐を書きます。
# 解答例1 # 入力 n = gets.to_i # n に対応した色を color に代入 color = if n == 1 "white" elsif n == 2 "black" elsif n == 3 "red" elsif n == 4 "blue" elsif n == 5 "yellow" elsif n == 6 "green" elsif n == 7 "orange" elsif n == 8 "pink" elsif n == 9 "purple" end # color を出力 puts color
Ruby 解答例2
case文でも書くことが出来ます。
# 解答例2 # 入力 n = gets.to_i # n に対応した色を color に代入 color = case n when 1 "white" when 2 "black" when 3 "red" when 4 "blue" when 5 "yellow" when 6 "green" when 7 "orange" when 8 "pink" when 9 "purple" end # color を出力 puts color
Ruby 解答例3
番号順の色の配列を用意しておけば、条件分岐を書かずに番号対応した色が取得できます。
# 解答例3 # 色の設定 colors = ["white", "black", "red", "blue", "yellow", "green", "orange", "pink", "purple"] # なるべく少ない入力で配列を作るなら # split メソッド # colors = "white black red blue yellow green orange pink purple".split # % 記法 # colors = %w(white black red blue yellow green orange pink purple) # 入力 n = gets.to_i # n に対応した色を出力 puts colors[n - 1]
Python3 解答例1
if文を使って、1から9までの条件分岐を書きます。
# 解答例1 # 入力 n = int(input()) # n に対応した色を color に代入 color = "" if n == 1: color = "white" elif n == 2: color = "black" elif n == 3: color = "red" elif n == 4: color = "blue" elif n == 5: color = "yellow" elif n == 6: color = "green" elif n == 7: color = "orange" elif n == 8: color = "pink" elif n == 9: color = "purple" # color を出力 print(color)
Python3 解答例2
番号順の色の配列を用意しておけば、条件分岐を書かずに番号対応した色が取得できます。
# 解答例2 # 色の設定 colors = ["white", "black", "red", "blue", "yellow", "green", "orange", "pink", "purple"] # なるべく少ない入力で配列を作るなら # colors = "white black red blue yellow green orange pink purple".split() # 入力 n = int(input()) # n に対応した色を出力 print(colors[n - 1])
2問目: エレベーターの行き先 (paizaランク D 相当)
エレベータに乗った想定で、現在いる階 f1
と行きたい階 f2
が半角スペース区切りで与えられるので、"up" と "down" のどちらのボタンを押せば良いかを出力する問題です。
尚、f1, f2
は 1F, 2F, 3F, 4F, 5F, 6F, 7F, 8F, 9F
で与えられ、f1
と f2
が同じになることはありません。
入出力例
現在 1F
で、 7F
に行きたいなら up
を出力。
現在 5F
で、 2F
に行きたいなら down
を出力。
INPUT1 = <<"EOS" 1F 7F EOS OUTPUT1 = <<"EOS" up EOS INPUT2 = <<"EOS" 5F 2F EOS OUTPUT2 = <<"EOS" down EOS
Ruby解答例1
"数字+F" の数字部分を整数型に変換してf1, f2
に代入し、押すボタンを判別する方法です。
# 解答例1 # 入力 # input_strings = gets.split # 文字列を半角スペースで分割して配列を生成 # f1 = input_strings[0].to_i # 1 番目の文字列を整数に変換 # f2 = input_strings[1].to_i # 2 番目の文字列を整数に変換 # 上記を短くまとめて書くと f1, f2 = gets.split.map(&:to_i) # f1 と f2 を比較して押すボタンを出力 if f1 < f2 puts "up" else puts "down" end
Ruby解答例2
今回の問題では 1F ~ 9F までなので、文字列のまま比較することが出来ます。ついでに三項演算子で入力数削減。
# 解答例2 # 入力 f1, f2 = gets.split # f1 と f2 を文字列のまま比較して押すボタンを出力 puts f1 < f2 ? "up" : "down"
Python解答例1
"数字+F" の数字部分を整数型に変換してf1, f2
に代入し、押すボタンを判別する方法です。
# 解答例1 # 入力 # input_strings = input().split() # 文字列を半角スペースで分割して配列を生成 # f1 = int(input_strings[0][:-1]) # 1 番目の文字列の末尾 (F) を削除して整数に変換 # f2 = int(input_strings[1][:-1]) # 2 番目の文字列の末尾 (F) を削除して整数に変換 # 上記を短くまとめて書くと f1, f2 = map(lambda x: int(x[:-1]), input().split()) # f1 と f2 を比較して押すボタンを出力 if f1 < f2: print("up") else: print("down")
Python解答例2
文字列のまま比較し、三項演算子で入力数削減。
# 解答例2 # 入力 f1, f2 = input().split() # f1 と f2 を文字列のまま比較して押すボタンを出力 print("up" if f1 < f2 else "down")
3問目: 長方形の面積 (paizaランク D 相当)
長方形の隣接する2辺 e1,e2 が半角スペース区切り与えられ、面積を出力する問題です。
ただし、e1
か e2
が 0 の場合は、 invalid
を出力します。
入出力例
e1 = 7, e2 = 5
なら 7 * 5 = 35
で 35
を出力する。
e1 = 0, e2 = 10
なら invalid
を出力する。
INPUT1 = <<"EOS" 7 5 EOS OUTPUT1 = <<"EOS" 35 EOS INPUT2 = <<"EOS" 0 10 EOS OUTPUT2 = <<"EOS" invalid EOS
Ruby解答例1
e1, e2 のどちらかが0 だと面積も0になるので、とりあえず先に面積 s = e1 * e2 の計算を行い、s が 0 を超えるなら s を出力、 s が 0 なら invalid
を出力します。
# 解答例1 # 入力 # input_strings = gets.split # 半角スペースで分割して文字列の配列を生成 # e1 = input_strings[0].to_i # 1 番目の文字列を整数に変換 # e2 = input_strings[1].to_i # 2 番目の文字列を整数に変換 # ↓ 短く書くと e1, e2 = gets.split.map(&:to_i) # 面積計算 s = e1 * e2 # 面積 s または invalid を出力 if s > 0 puts s else puts "invalid" end
Ruby解答例2
e1, e2
を配列で受け取り、inject
メソッドで配列の総積s(e1 * e2)を求め、s が 0 を超えるなら s を出力、 s が 0 なら invalid
を出力します。
# 解答例2 # 入力から面積を計算 # 半角スペースで区切られた文字列を整数の配列にして、 # 配列の要素を全て掛け合わせた値(総積)を s に格納する s = gets.split.map(&:to_i).inject(:*) # 面積 s または invalid を出力 puts s > 0 ? s : "invalid"
Python3 解答例1
面積 s = e1 * e2 の計算を行い、s が 0 を超えるなら s を出力、 s が 0 なら invalid
を出力します。
# 解答例1 # 入力 # input_strings = input().split() # 半角スペースで分割して文字列の配列を生成 # e1 = int(input_strings[0]) # 1 番目の文字列を整数に変換 # e2 = int(input_strings[1]) # 2 番目の文字列を整数に変換 # ↓ 短く書くと e1, e2 = map(int, input().split()) # 面積計算 s = e1 * e2 # 面積 s または invalid を出力 if s > 0: print(s) else: print("invalid")
Python3 解答例2
e1, e2
を配列で受け取り、math.prod
メソッドで配列の総積s(e1 * e2)を求め、s が 0 を超えるなら s を出力、 s が 0 なら invalid
を出力します。
# 解答例2 import math # 入力から面積を計算 # 半角スペースで区切られた文字列を整数の配列にして、 # 配列の要素を全て掛け合わせた値(総積)を s に格納する s = math.prod(map(int, input().split())) # 面積 s または invalid を出力 print(s if s > 0 else "invalid")
4問目: セール販売 (paizaランク C 相当)
1行目で購入商品数 n が与えられ、続く n 行の半角スペース区切りで購入品名と価格が与えられ、合計金額を求める問題です。
但し、合計金額には以下のルールが適用されます。
- ズボン(pants)を1点以上買っていて、
- 2000円以上お買い上げ
の方は、合計金額から 500円 引きとなります。
入出力例
"shirt 1000", "shoes 2000", "shirt 500" を購入した場合、合計金額は 3500円なので 3500 を出力
"shirt 500", "pants 1000", "pants 500", "shoes 2000" を購入した場合の合計金額は 4000円となるが、pants を1点以上購入かつ合計金額が2000円以上なので 4000-500 = 3500円 で 3500 を出力
INPUT1 = <<"EOS" 3 shirt 1000 shoes 2000 shirt 500 EOS OUTPUT1 = <<"EOS" 3500 EOS INPUT2 = <<"EOS" 4 shirt 500 pants 1000 pants 500 shoes 2000 EOS OUTPTU2 = <<"EOS" 3500 EOS
Ruby解答例1
- 整数 n を受け取る
- lines(Array) を空で初期化する
- n 回のループを回す
- 1行分の文字列を lines 末尾に追加
- items (Array) を空で初期化する
- total を 0 で初期化する
- lines の先頭から順に line で参照するループを設定
- line を半角スペースで分割して, item, price へ代入する
- item を items 末尾に追加する
- price を整数型に変換して、total に加算する
- もし「ズボン(pants) を1点以上購入」かつ「total が 2000 以上」なら total から 500 減算する
- total を出力する
Ruby 解答例1
# 解答例1 # 入力 n = gets.to_i # 1 行の入力を受け取って整数型に変換 lines = [] # 購入履歴を格納するための空のリストを用意 n.times { lines << gets.chomp } # n 行の入力を受け取って lines に追加 # 上記を短く書くと(n は不要になる) # _, *lines = $stdin.read.split("\n") # 購入品 item と合計金額 total を記録する items = [] total = 0 lines.each do |line| item, price = line.split items << item total += price.to_i end # もし "pants" を購入かつ total が 2000 円以上なら 500 円引き if items.include?("pants") && total >= 2000 total -= 500 end puts total
Ruby 解答例2
購入品のリストを作る代わりに、pants を買ったかどうかのフラグを設定する書き方です。
# 解答例2 # 入力 _, *lines = $stdin.read.split("\n") # "pants" を買ったか?のフラグ と合計金額 total を記録する pants = false total = 0 lines.each do |line| item, price = line.split pants = true if item == "pants" total += price.to_i end # もし pants を購入かつ total が 2000 円以上なら 500 円引き if pants && total >= 2000 total -= 500 end puts total
Python3 解答例1
# 解答例1 # 入力 # n = int(input()) # 1 行の入力を受け取って整数型に変換 # lines = [] # 空のリストを用意 # for _ in range(n): # lines.append(input()) # n 行の入力を受け取って配列 list 末尾に追加 # 上記を短く書くと (n は不要になる) _, *lines = open(0).read().strip().split("\n") # 品物 item のリストと合計金額 total を記録する items = [] total = 0 for line in lines: item, price = line.split() items.append(item) total += int(price) # もし "pants" を購入かつ total が 2000 円以上なら 500 円引き if "pants" in items and total >= 2000: total -= 500 print(total)
Python3 解答例2
# 解答例2 # 入力 _, *lines = open(0).read().strip().split("\n") # 合計金額 total と "pants" を買ったかを記録する pants = False total = 0 for line in lines: item, price = line.split() if item == "pants": pants = True total += int(price) # もし pants を購入かつ total が 2000 円以上なら 500 円引き if pants and total >= 2000: total -= 500 print(total)
今回のまとめ
基本的な文法(標準入力・出力、配列、繰り返し、条件分岐)が出来れば特に難しくない問題でした。
手数(打鍵数)が少ない書き方も覚えておけば、タイムアタックの時に便利かもしれませんね(*'ω'*)