競技プログラミングの楽しみ 
エンジニア 
@na_o_ys
自己紹介 
• 大阪出身 25 歳 
• 大学院では暗号理論を研究 
• 新卒入社の SIer から逃げ出して、弊社に入社 
• 趣味:競技プログラミング
問題1. Pair of Primes 
入力として整数 N (N <= 10000) が与えられる。 
1 から N までの数字を昇順, 降順に並べる。 
1 2 3 4 5 6 7 8 9 ... N 
N ... 9 8 7 6 5 4 3 2 1 
上下のペアのうち両方が 素数 であるものの個数を 
出力せよ。 
※実行時間 1 秒以内
N = 9 の場合 
• 答えは 3 
1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1
方針 
N の最大値は 10000 
1. 10000 以下の素数リストを生成する 
2. (1, N), (2, N-1), (3, N-2), ... が素数リストに含まれるか 
どうか確かめる 
3. 個数を出力
実装してみます
競技プログラミングの楽しみ その1 
実装・提出して Accept されると気持ち良い
ポイント 
実行時間に関して 
• 1 秒で実行できるループ回数(計算量) : 108 回くらい 
– C++ の場合 
• 試し割りで素数表を作る計算量: O(N√N) 
– 今回は N の最大値は 104 
– N√N = 106 回程度のループで済む
ポイント 
もし N の最大値が 106 だったら…? 
• 試し割りでは間に合わない ( N√N = 109 ) 
• もっと高級なアルゴリズムを実装しなきゃいけない 
– e.g. エラトステネスのふるい
競技プログラミングの楽しみ その2 
問題の制約から, 適切なアルゴリズムを選択する
問題2. Sum equals N 
長さ 106 の整数配列 M = { m1, m2, m3, ..., m106 } と, 
整数 N が与えられる。 
M の要素から 2 つ選ぶとき、和が N になる組み合わせは 
存在するか? 
存在するなら “OK”, しないなら “NO” と出力せよ。 
※実行時間 1 秒以内
全通り試す場合 
• 1 つ目の選び方は 106 通り, 2 つ目も 106 通り 
• ループ回数は 106 * 106 = 1012 
• 1 秒じゃ終わらない
工夫 
• 1 つ目の値を固定してみる 
– 1 つ目の値が a ならば, 2 つ目は N ‒ a 
– 配列 M をソートしておけば, N ‒ a が配列 M に存在 
するかどうか, 二分探索で効率的に調べれられる 
• 1 つ目の値についてのみ全通り試せば良い 
• 計算量は 106 * log 106 ≒ 107 
• 間に合う!
競技プログラミングの楽しみ その3 
工夫して制約条件を突破する!
競技プログラミングは役に立つ 
1. 計算量の見積もりが効くようになる 
– ボトルネック以外を効率化しても無意味という実感 
2. 複雑なロジックの実装力が上がる 
– たまにある複雑なデータ抽出処理とか 
3. 複雑なロジックの読解力が上がる 
– 競技プログラミングでは他人のコードを読む機会が多い
競技プログラミングは 
楽しいだけじゃなくて役に立つ 
今すぐ参加だ!
コンテスト 
Web上で定期的に大会が開催されている 
TopCoder Codeforces AtCoder 
一番メジャー 最近人気 問題が日本語 
月3回開催 月5回開催 不定期開催 
• 1~2 時間で 3~6 個の問題を解く 
• 早く解くほど高得点 
• 結果によってレーティングが変化する
TopCoderのレーティング分布 
人数 
レーティング
レーティング履歴も見られる
まとめ 
• 競技プログラミングは楽しい 
• 競技プログラミングは役に立つ 
• コンテストが結構頻繁に開かれる 
興味が湧いた方は… 
– ブログやってます: http://na-o-s.hateblo.jp/ 
面白かった問題の解説とか 
– 有志によるコンテストカレンダー: http://topcoder.g.hatena.ne.jp/
ご清聴ありがとうございました

競技プログラミングの楽しみ