AtCoder Beginner Contest 163にRubyで挑戦しました

AtCoder Beginner Contestに2度目の挑戦

4月19日に開催されたAtCoder Beginner Contest 163に参加しました。言語はRubyです。

AtCoder Beginner Contestは、3月に初めて参加し今回が2回目の挑戦でした。前回は一番簡単なA問題だけ正解、B以上は問題は見ましたがコードの見当もつかずに諦めました。

今回は、A・B問題でAC (Acceptedで正解という意味)を出すことができました!

C問題も自分としてはできたと思って提出したのですが、TLE (Time Limit Exceededで実行時間超過という意味)でした。

AtCoderのコンテストは、終了後であれば問題やコードを公開しても問題ないので、復習してさらによい答えがないか考えていきたいと思っています。またブログにも書くつもりですが、取り急ぎ今日は問題と自分の解答だけ紹介します。

AtCoder Beginner Contest 163 問題と提出コード

A - Circle Pond

A - Circle Pond

問題文
半径 R の円の周長を出力してください。

制約
1 ≤ R ≤ 100
入力は全て整数である。

入力
入力は以下の形式で標準入力から与えられます。
R

出力
円の周長を出力せよ。 なお、想定解答との絶対誤差または相対誤差が 10−2 以下であれば正解として扱われる。

提出したコード(AC:正解)

r = gets.to_i
puts r * 2 * Math::PI

B - Homework

B - Homework

問題文
高橋君の夏休みは N 日間です。
夏休みの宿題が M 個出されており、i 番目の宿題をやるには Ai 日間かかります。
複数の宿題を同じ日にやることはできず、また、宿題をやる日には遊ぶことができません。
夏休み中に全ての宿題を終わらせるとき、最大何日間遊ぶことができますか?
ただし、夏休み中に全ての宿題を終わらせることができないときは、かわりに -1 を出力してください。

制約
1 ≤ N ≤ 106, 1 ≤ M ≤ 104, 1 ≤ Ai ≤ 104

入力
入力は以下の形式で標準入力から与えられる。
N M
A1...AM

出力
高橋君が遊ぶことのできる日数、または、-1 を出力せよ。

提出したコード(AC:正解)

n, m = gets.split.map(&:to_i)
homeworks = gets.split.map(&:to_i)
homework_days = homeworks.sum
if homework_days > n
    puts -1
else
    puts n - homework_days
end

C - management

C - management

問題文
N 人の社員からなる会社があり、各社員には 1,...,N の社員番号が割り当てられています。
社員番号 1 の社員以外の全ての社員には、自分より社員番号が小さい直属の上司がちょうど 1 人います。
X さんが Y さんの直属の上司であるとき、Y さんは X さんの直属の部下であるといいます。
社員番号 i の社員の直属の上司の社員番号が Ai であることが与えられます。各社員について直属の部下が何人いるか求めてください。

制約
2 ≤ N ≤2×105, 1 ≤ Ai < i

入力
入力は以下の形式で標準入力から与えられる。
N
A2...AN

出力
社員番号 1,2,...,N のそれぞれの社員について、直属の部下が何人いるか、改行区切りで出力せよ。

提出したコード(TLE:実行時間超過)

n = gets.to_i
numbers = gets.split.map(&:to_i)
(1..n).each do |x|
    puts numbers.count(x)
end

感想

いい変数名が全然思いつかない!

今回は始めるのが1時間近く遅れてしまったこともあって焦りました。でも結局いい変数名の付け方を知らないので、やっぱりうまくつけられず。そこらへんも勉強していきたいところです。

自分は一流の競技プログラマを目指しているわけではなく、あくまで学習の一環として、あと単純に楽しいからという理由でやっているのですが、問題をやってみると何かしら発見があり勉強になります。

各問題について詳しくは、後日また書きます。自分のレベル的にA〜C問題だけになります。