LoginSignup
4
1

More than 3 years have passed since last update.

競プロの世界の端っこを覗いてみた(AtCoder Beginners Selection)

Last updated at Posted at 2019-12-08

はじめに

最近なぜか競プロ系のツイートがタイムラインに流れてくるので、ちょっとその世界の端っこを覗いてみることに。

DISCLAIMER: これは感想文です。競技プログラミングについては、ためになる記事が他にたくさんあるのでそちらをご覧ください

プログラミング系サイト

ざっと調べてみたところ結構あるみたい。

  • AOJ
    • 大学系のコンテストサイトっぽい
  • AtCoder
    • コンテスト系サイト。日本では一番有名?
  • LeetCode
    • グローバルで一番有名か。過去問集みたいな感じ。GAFAなどの実際の面接にだされた問題もあるとかないとか
  • HackerRank
    • デベロッパと企業のマッチングサイト。コード書いてアピールするタイプっぽい
  • CodeChef
    • ぱっと見、コンテスト系サイト
  • exercism
    • 好きな言語選んで、コード提出したらメンターがみてくれる感じの学習サイト
  • CodeWars

英語には抵抗ないので、LeetCodeやろうとしたのだが、回答をどう書けばいいのかわかりにくくて、結局 Atcoder にする

2019/12/22 - LeetCode やってみたらこっちの方が遥かにUIはいいし、わかりやすい。今後はLeetCode にすると思う。英語に抵抗なければこっちをおすすめ。

自分なりの遊び方

  • 全問を rubygo で書き比べてみたら面白いかも。解きやすさや、解答のスコア(メモリ量や速度)をみてみるのは面白いかも。go の勉強にもなるだろう(あとでやってみる)
  • テストを書きながらやってもいいかも

AtCoder

Atcoderはいろいろと丁寧なガイドがある

AtCoder Beginners Selection

解答

ここに解答。まだ ruby だけ。

Welcome to AtCoder

特に書くことがない

Product

特に書くことがない

Placing Marbles

特に書くことがない

Shift only

特に書くことがない

Coin

順列組み合わせ的な数学的手法できれいに解こうとするが失敗。単純に三重ループをぶん回すほうがよいというオチ

Some Sums

array.sum が2.3では実装されていないところでちとハマったが、それ以外は簡単

Card Game

文字列を delete で値で消すと、マッチする部分が全て消えるので、delete_at を使う。このためにary.index する。計算回数を無闇に増やさないしないようにしたいところ

Kagami Mochi

uniq 使えば一行でかける。もちの個数 N は使わなくても解ける

Otoshidama

各お札の枚数の組み合わせをつくるのに少し時間かかった。あと「複数の可能性が考えられるときは、そのうちどれを出力してもよい」という条件なのでテストがいままでと書き方変わる。

Daydream

  • このあたりから面白くなってくる
  • S から配列の文字列を消していって、最終的に S がなくなるかどうかかという判定をすることにした
  • T を考えるときに、前方一致でやると S = dreameraser は T = dreamdreamer に一致してしまう。前者は次に eraser を持ってくることで S = T つまりYES となるが、後者の場合は NO になってしまう。つまり最初のマッチだけでなく、マッチした全て(dreamdreamer)をTの候補としてあつかうことになるので、分岐が増えてうまくない
  • 1≦|S|≦105 なので入力する文字はめっちゃ長いことがありえる。下手すると制限時間内(2sec)に終わらない(ここで、解けるのに時間がオーバ... となる)
  • どうやら、前方一致ではなく、後方一致するといいようだ(後ろからマッチしていくと上記のようなことはなく候補は一意に決まる)
  • 後方一致で書いてみるものの、それでも制限時間オーバ TLE (Time Limit Exceeded) をくらう
  • 後方一致してその部分を消すときの正規表現が遅い gsub!(/word$/, '') と気付き、予め文字の長さを整数を渡して、文字を消すときには正規表現を使わずに slice!(x..y)で削除することで、全テストをパス(2s以上が100msへ)
  • あとで気づくのが、消していく順番さえ間違えなければ S に対する全置換 gsub! だけで対応でき、3行くらいのコードで書ける。OMG...

Traveling

このあたりになると、まず計算量のオーダが気になるようになる。この問題で正攻法で N 回動いた場合に到達する点を列挙とかやると、N10^5 までありえるので、死ぬことがすぐにわかる。

総評

それなりに楽しみながら解くことができました。

スタックしたと思ったら

なんでうまくいかないんだ... となったら

参考にさせていただいたサイト

競技プログラミング系のサイトをググるとGoogle入社の話につながっていく法則を発見した。

感想文

  • ああ、みんなこんなふうにプログラミングを楽しんでいるのね
  • この Beginners Selection、いい感じの問題が揃っている印象
  • 🐜本とか、🐅本とか、🌀本とかで基礎をやり直したくなる
  • 競プロは数学じゃない。問題を数学的に綺麗に解こうとせず、ループぶん回して解決する方がいいものもある
  • アイデアをコードにするのはやっぱり面白い
  • やっぱり ruby の書きやすさは、ぱんぱねぇ
  • 今回のやつを go でも書いてみる
  • 普段はメタレイヤの業務で死んでいるが、プログラミングは今後も暇をみつけてやるぜ
  • 開始時間指定のコンテストじゃなくて、空き時間にコツコツ問題といてスコア上げていく系のがやりたい
4
1
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
4
1