LoginSignup
19
31

競技プログラミングに入門してみよう!

Posted at

初めに

所属するスクール内でイベント「競技プログラミングに入門してみよう!」を開催した際の資料です。

AtCoderに新規登録する

  • AtCoderにアクセスする
    https://atcoder.jp/home
  • 右上の新規登録をクリック
  • 必要な情報を入力して新規登録を完了させる
    (今回は解答解説までイベント内で実施するため、できてなくても問題はありません)

rubyの実行環境を用意する

AtCoderでは解答のコードを打ち込むことができ、そのコードが正解かどうかを判定してくれる仕組みがあります。
なので、webサイト単体でも完結していますが、自分で実行環境を用意しておくと、コードの動きを途中で確認しながら解くことができるのでおすすめです。
今回はrubyの実行環境をdockerで構築して使っていきます。
https://zenn.dev/bloomer/articles/98df661f7c339e
上記の記事を参考にして進めます。

好きなディレクトリに移動して、今回の作業用ディレクトリを用意する。

$ mkdir ruby_study
$ cd ruby_study

エディタで作成したディレクトリを開きましょう。
vscodeで設定が完了していればcode ディレクトリ名で開けます。
もしくはフォルダを開くボタンから指定などでもいけます。

docker環境構築に必要なファイルを作成する。

$ touch Dockerfile compose.yaml Gemfile Gemfile.lock

Dockerfileの中身

FROM ruby:3.2.2
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
ENV LANG=ja_JP.UTF-8
ENV TZ=Asia/Tokyo

compose.yamlの中身

compose.yaml
version: '3.7'
services:
  app:
    build: .
    tty: true
    ports:
      - 3000:3000
    volumes:
      - .:/app

dockerを起動する

$ docker compose up

ターミナルの新しいタブを開いて、コンテナの中に入る

$ docker compose exec app bash

コンテナに入った状態でrubyコマンドを打てば、rubyファイルを実行できます。

/app# ruby ファイル名.rb

環境ができているかの確認をしてみましょう。
rbファイルを作成する

/app# touch test.rb

作成したファイルにコードを書いてみる

puts "hello world"

rubyを実行して、hello worldがコンソールに表示されていればokです。

/app# ruby test.rb 
hello wolrd

問題を解く際には、問題ごとに問題名をつけたrbファイルを作るのがおすすめです。

問題を解いてみよう

AtCoder Beginners Selectionから問題を選んでいきます。

  • ログインした状態で画面左上のコンテストをクリック
  • 画面左側のエリアに常設中のコンテスト欄があり、そこにAtCoder Beginners Selectionがあるのでクリック
  • 問題タブをクリックして問題一覧画面が表示されたら準備完了

PracticeA - Welcome to AtCoder

必須の事前知識

解くために必要な知識

  • 指定された入力をコードで処理し、指定された出力をするコードを書く
  • getsメソッド
    入力を1行、文字列で取得する。
  • chompメソッド
    改行文字を取り除く。
  • この2つのメソッドに色々と加えてコードを書いていきましょう。
解答解説
# 1行目のaを数字で取得して変数に格納
a = gets.to_i
# 2行目のbとcを[b, c]で取得してそれぞれを個別に変数に格納
b,c = gets.chomp.split(" ").map(&:to_i)
# 3行目のsを文字列で取得して変数に格納
s = gets.chomp
# 用意した変数を使って、解答を出力する
print ("#{a+b+c} #{s}\n")

ABC086A - Product

解答解説
a, b = gets.chomp.split(" ").map(&:to_i)
product = a * b
if product % 2 == 0
  puts "Even"
else
  puts "Odd"
end

ABC081A - Placing Marbles

解答解説 数字の配列の形で入力を受け取り、その配列内の1の数をcountメソッドで数える。
s = gets.split("").map(&:to_i)
puts s.count(1)

ABC081B - Shift only

解答解説

繰り返し処理を使って、全ての整数を2で割る動作を全ての整数が偶数であるかぎり繰り返し、その数をカウントする。

# 受け取ってみたがいらない
N = gets
# 数字の配列の形で受け取る
numbers = gets.split(" ").map(&:to_i)
# 答え用の変数に初期値の0を代入
ans = 0
# 配列の全ての要素が偶数であるかぎり繰り返す
while numbers.all? { |n| n.even? }
  # 配列の全ての要素を2で割って配列にする
  numbers = numbers.map { |n| n / 2 }
  # 答え用の変数に1を足す
  ans += 1
end
# 答えを出力する
puts ans

ABC087B - Coins

解答解説 まずは入力を受け取る 解答用のcount変数を0で用意しておく a,b,c3つの硬貨の枚数を範囲指定して、繰り返し処理をネストさせる。 これによって、i, j, kに全ての枚数の組み合わせが入れられる。 中のif文でちょうどx円になる組み合わせを検知し、countに+1する。 全ての組み合わせを試し終わると、count変数に合計x円になる組み合わせの数が入っている。
a = gets.to_i
b = gets.to_i
c = gets.to_i
x = gets.to_i

count = 0

(0..a).each do |i|
  (0..b).each do |j|
    (0..c).each do |k|
      if 500 * i + 100 * j + 50 * k == x
        count += 1
      end 
    end 
  end 
end 

オマケ

githubに保存する

問題を解いたコードをgithubに保存すれば、自分の頑張りを記録して管理することができます。
https://qiita.com/sugimount-a/items/415116b2fc7ef2bfd74d
興味がある方は上記のようなネット上の記事を参考に挑戦してみてください。

AtCoder Beginners Selectionが終わったら

https://kenkoooo.com/atcoder/#/table/
AtCoder Problemsという過去問をまとめてくれているサイトがあるので、ここでABC(AtCoder Beginner Contest)の過去問を解いていくのがおすすめです。

というか、こちらの記事に今日の内容も含めて詳しく載っているので、参考にしてください。
https://qiita.com/drken/items/fd4e5e3630d0f5859067

参考資料

https://atcoder.jp/home
https://zenn.dev/bloomer/articles/98df661f7c339e
https://qiita.com/sugimount-a/items/415116b2fc7ef2bfd74d
https://kenkoooo.com/atcoder/#/table/
https://qiita.com/drken/items/fd4e5e3630d0f5859067

以上。

19
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
31