More Related Content
Similar to 競技プログラミングの楽しみ (6)
競技プログラミングの楽しみ
- 2. 自己紹介
• 大阪出身 25 歳
• 大学院では暗号理論を研究
• 新卒入社の SIer から逃げ出して、弊社に入社
• 趣味:競技プログラミング
- 3. 問題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 秒以内
- 4. N = 9 の場合
• 答えは 3
1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1
- 5. 方針
N の最大値は 10000
1. 10000 以下の素数リストを生成する
2. (1, N), (2, N-1), (3, N-2), ... が素数リストに含まれるか
どうか確かめる
3. 個数を出力
- 8. ポイント
実行時間に関して
• 1 秒で実行できるループ回数(計算量) : 108 回くらい
– C++ の場合
• 試し割りで素数表を作る計算量: O(N√N)
– 今回は N の最大値は 104
– N√N = 106 回程度のループで済む
- 9. ポイント
もし N の最大値が 106 だったら…?
• 試し割りでは間に合わない ( N√N = 109 )
• もっと高級なアルゴリズムを実装しなきゃいけない
– e.g. エラトステネスのふるい
- 11. 問題2. Sum equals N
長さ 106 の整数配列 M = { m1, m2, m3, ..., m106 } と,
整数 N が与えられる。
M の要素から 2 つ選ぶとき、和が N になる組み合わせは
存在するか?
存在するなら “OK”, しないなら “NO” と出力せよ。
※実行時間 1 秒以内
- 12. 全通り試す場合
• 1 つ目の選び方は 106 通り, 2 つ目も 106 通り
• ループ回数は 106 * 106 = 1012
• 1 秒じゃ終わらない
- 13. 工夫
• 1 つ目の値を固定してみる
– 1 つ目の値が a ならば, 2 つ目は N ‒ a
– 配列 M をソートしておけば, N ‒ a が配列 M に存在
するかどうか, 二分探索で効率的に調べれられる
• 1 つ目の値についてのみ全通り試せば良い
• 計算量は 106 * log 106 ≒ 107
• 間に合う!
- 20. まとめ
• 競技プログラミングは楽しい
• 競技プログラミングは役に立つ
• コンテストが結構頻繁に開かれる
興味が湧いた方は…
– ブログやってます: http://na-o-s.hateblo.jp/
面白かった問題の解説とか
– 有志によるコンテストカレンダー: http://topcoder.g.hatena.ne.jp/