Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

競技プログラミング練習会2015 Normal 第2回

1,757 views

Published on

2015/04/17 京大マイコンクラブ部室.
スタックとキュー/全探索/累積和

Published in: Engineering
  • Be the first to comment

競技プログラミング練習会2015 Normal 第2回

  1. 1. 2015/04/17 長嶺英朗(ID:hnagamin) 競技プログラミング練習会 2015 Normal 第2回
  2. 2. 目次 ● スタックとキュー ● 全探索 – 幅優先探索 – 深さ優先探索 ● 累積和
  3. 3. データ構造 ● データ構造は多数のデータをある秩序に従って保 存しておくための構造です – 例) 配列、ハッシュテーブル、木、スタック、キュー… ● データ構造には様々な種類があり、それぞれ得意な ことと不得意なこと、可能なことと不可能なことがあ ります ● 今日はスタックとキューの話をします
  4. 4. スタック ● 「後入れ先出し」 (Last In, First Out)のデータ構造 ● 次のことがO(1)でできる ● push: 先頭に要素を追加する ● pop: 先頭の要素を取り出す ● 本の山みたいなイメージ push pop
  5. 5. キュー ● 「先入れ先出し」 (First In, First Out)のデータ構造 ● 次のことがO(1)でできる ● enqueue: 先頭に要素を追加する ● dequeue: 末尾の要素を取り出す ● 店の行列的なイメージ enqueue dequeue
  6. 6. スタックを使う問題の例 http://poj.org/problem?id=2559
  7. 7. 全探索
  8. 8. 全探索 ● いくつかの組合せの中からある特定のものを探す とき、考えるべき組合せが比較的少ない場合にはそ れらを全て調べてしまうのが有効なことがある ● 「比較的少ない」: 106通りくらい
  9. 9. 全探索が有効な例 ● 3×3魔法陣の解の個数を求める ● 3x3マスに1~9の数字を入れて魔法陣か確かめる ● 考えるべき組合せは9!通り ● 9! = 362880 < 106 ● 間に合う 2 9 4 7 5 3 6 1 8
  10. 10. 全探索が有効な例 ● 8クイーン問題の解のひとつを求める ● 8x8チェス盤に8つのクイーンを置く ● どのクイーンも他の駒の利きにないよう置く
  11. 11. 8クイーン問題の解の一例 http://ja.wikipedia.org/wiki/エイト・クイーン
  12. 12. 全探索が有効な例 ● 普通に並べると64C8 通り – ちょっと大きい ● 工夫が必要
  13. 13. 全探索が有効な例 ● 普通に並べると64C8 = 4426165368 通り – ちょっと大きい ● 工夫が必要
  14. 14. 全探索が有効な例 ● よく考えると、2つのクイーンは同じ列・同じ行には 並ばない ● {1, 2, ... 8} の順列をクイーンの位置に対応させる ● 8! = 40320 ● 間に合う (7, 5, 3, 1, 6, 8, 2, 4)
  15. 15. 全探索 ● 考えるべき状態を木として扱うことが多い 1 2 3 4 5 1 31 2 1 4 2 1 …
  16. 16. 18 1914 深さ優先探索 ● 葉に到達するまで子要素を探索してから次の子要 素を探索する 1 2 11 15 3 5 8 12 13 16 17 4 6 7 9 10
  17. 17. 深さ優先探索 ● スタックを使って深さ優先探索が実現できる ● まだ探索していない頂点をスタックに積んでから、 スタックから頂点を取り出して深さ優先探索する
  18. 18. 18 1917 幅優先探索 ● 子要素を全て探索してから子要素の子要素を探索 する ● 根に近い順に探索していく 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  19. 19. 幅優先探索 ● キューを使って幅優先探索が実現できる ● 今見ている頂点の子要素を全てキューに突っ込ん でから、キューから頂点を1つ取りだして幅優先探 索する
  20. 20. 深さ優先探索のココがすごい! ● メモリ消費量が幅優先に比べて少ない! ● 再帰を使うことで楽に書ける! – 再帰を使って書くときは、暗黙のうちにコールスタックを 使っている ● 葉に至るまでが長い分枝が存在するとつらい! – 木の深さが有限でない場合終わらないことがある
  21. 21. 幅優先探索のココがすごい! ● ある種の最小解が求まる! – 例えば、頂点として迷路内の座標を設定しゴールに向 かって幅優先探索すると迷路を出るための最短経路が 求まる ● (解があれば)(木の深さが有限でなくても) 必ず見つける! ● メモリを大量に使う!
  22. 22. 累積和
  23. 23. 要求 ● 長さNの配列が与えられて、その中にはN個の数が 格納されている ● q個のクエリ(問題)が与えられるので、それに答える – 問題: 「i番目からj番目までの要素の和を答えよ」 ● N 10≦ 6 , q 10≦ 6
  24. 24. 愚直な解法 ● 各クエリに対して、一つひとつ和を求めていく
  25. 25. 愚直な解法 ● 各クエリに対して、一つひとつ和を求めていく ● O(qN) – 各クエリの処理に最大O(N)回の計算が必要 – クエリはq個 ● qN 10≦ 12 – ちょっと大変
  26. 26. 累積和 ● クエリを処理する前に予めSi = (0番目からi番目ま での要素の和)を求めておく ● 各クエリに対してSj - Si-1を返せば良い 3 1 4 1 5 9 2 63 1 4 1 5 9 2 6
  27. 27. 累積和 ● クエリを処理する前に予めSi = (0番目からi番目ま での要素の和)を求めておく ● 各クエリに対してSj - Si-1を返せば良い 3 1 4 1 5 9 2 6 3 4 8 9 14 23 25 31
  28. 28. 計算量 ● Siを求めるのにO(N) – Si = Si-1 + ai を利用する ● 各クエリに対してO(1) ● 従って、計算量はO(N + q) ● 間に合う

×