Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HUIT新歓2024「競技プログラミング、やってみませんか?」

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Slephy Slephy
April 05, 2024

 HUIT新歓2024「競技プログラミング、やってみませんか?」

北大IT研究会(HUIT)の2024年度新歓で使用した資料。
競技プログラミングの入門を促す内容。

Avatar for Slephy

Slephy

April 05, 2024
Tweet

Other Decks in Programming

Transcript

  1. 自己紹介 • Handle: Slephy • 所属: 北海道大学 工学部 情報エレクトロニクス学科 •

    学年: 学部4年 • 出身: 札幌 • 趣味: 競技プログラミング(4年目) • 好きな言語: C++ • 好きなポケモン: パモ, ワンパチ https://zukan.pokemon.co.jp/detail/0921 かわいい 私のアイコン
  2. プログラミング入門の次は何をする? プログラミング 入門 アプリ開発 Web開発 ゲーム開発 機械学習 ハードウェア 開発 自然言語処理

    ITの世界は広くて深い 入門を終えたばかりの初心者は挫折しやすい 変数 if for 飛躍が大きい
  3. 競技プログラミングとは -順位の付け方- G 600pt 問題 F 525pt 問題 E 500pt

    問題 D 400pt 問題 C 350pt 問題 B 200pt 問題 A 100pt 問題 複数の問題に2時間程度で挑戦する”コンテスト”が開催される 正解した問題の合計得点が高い人が良い順位になる 同点ならば早く回答した人が良い順位になる
  4. AtCoder Beginner Contest とは • AtCoder Beginner Contest • 略してABC

    • 毎週土曜(もしくは日曜)の午後9時から開催 • だれでも参加可能 • 100分間で7問を解いて点数や正答するまでの早さを競う • 週末夜にもかかわらず約10000人が参加する人気コンテスト
  5. まずは工夫が必要ない簡単な問題 1 2 3 4 5 6 7 8 9

    2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 N = 15 Input Yes Output N = 38 Input No Output 例 整数 𝑵𝑵 が与えられる。 𝑵𝑵 が九九表に含まれる数かどうかを判定せよ。 問題 参考: https://atcoder.jp/contests/abc144/tasks/abc144_b
  6. なぜこのプログラムは遅いのか • 現代のコンピュータは基本的な計算を1秒間におよそ𝟏𝟏𝟏𝟏𝟖𝟖回できる • 𝟏𝟏 ≤ 𝒂𝒂 ≤ 𝟏𝟏𝟎𝟎𝟔𝟔, 𝟏𝟏

    ≤ 𝒃𝒃 ≤ 𝟏𝟏𝟎𝟎𝟔𝟔 の範囲を全て調べるためには 𝟏𝟏𝟎𝟎𝟏𝟏𝟏𝟏回程度の計算が必要 • 先ほどの方法では Pythonで数時間かかってしまう パソコンは高速に計算することが可能 しかしどんな問題でも一瞬で解けるわけではない Point 原因
  7. より良いアルゴリズム 条件を満たす可能性がある 𝒂𝒂, 𝒃𝒃 をすべて検証する 従来のアルゴリズム 条件を満たす可能性がある 𝒂𝒂 をすべて検証する 𝒂𝒂

    を決めれば、それに対応する 𝒃𝒃 が条件を満たすかはすぐに判定できる 新しいアルゴリズム 𝑵𝑵 = 𝒂𝒂𝒂𝒂 より 𝒃𝒃 = 𝑵𝑵 𝒂𝒂 なので、 𝒂𝒂 を決めれば 𝒃𝒃 の値は決まる 重要な考察 𝟏𝟏𝟎𝟎𝟏𝟏𝟏𝟏回 𝟏𝟏𝟎𝟎𝟔𝟔回
  8. 高速化の必要がある問題 a = 3, b = 4 Input 81 Output

    a = 7, b = 16 Input 601 Output 34 = 81 716 = 33,232,930,569,601 自然数 𝒂𝒂, 𝒃𝒃 が与えられる。𝒂𝒂𝒃𝒃 の下3桁を出力せよ。 ただし 𝟏𝟏 ≤ 𝒃𝒃 ≤ 𝟏𝟏𝟎𝟎𝟏𝟏𝟏𝟏 であり、𝒃𝒃 は非常に大きな値かもしれない。 問題 例
  9. 素朴なアルゴリズム 71 = 7 72 = 71 × 71 =

    7 × 7 = 49 73 = 72 × 71 = 49 × 7 = 343 74 = 73 × 71 = 343 × 7 = 2,401 ⋮ 716 = 715 × 71 = 4,747,561,509,943 × 7 = 33,232,930,569,601 𝒃𝒃回の計算 a = 7, b = 16 Input ひとつひとつ 順番に求めていく アルゴリズム
  10. 問題点①の解決策 桁数の大きな掛け算はパソコンでも時間がかかる 問題点① 下三桁だけで計算すればよい 解決策 1234 ×5678 9872 8638 7404

    6170 7006652 234 ×678 1872 1638 1404 158652 下三桁だけを抜き出して計算しても 答えは変わらない 計算途中でも下三桁以外の情報は 捨ててよい 証明略
  11. 解決策①を適用した様子 71 ≡ 7 72 ≡ 71 × 71 ≡

    7 × 7 ≡ 49 73 ≡ 72 × 71 ≡ 49 × 7 ≡ 343 74 ≡ 73 × 71 ≡ 343 × 7 ≡ 2,401 ≡ 401 ⋮ 716 ≡ 715 × 71 ≡ 943 × 7 ≡ 9,601 ≡ 601 a = 7, b = 16 Input 以下、法を1000とする 大きな数を使わずに問題を扱うことに成功
  12. 問題点②の解決策(𝒃𝒃 = 𝟐𝟐𝒌𝒌 のとき) 71 ≡ 7 72 ≡ 71

    × 71 ≡ 7 × 7 ≡ 49 74 ≡ 72 × 72 ≡ 49 × 49 ≡ 2,401 ≡ 401 78 ≡ 74 × 74 ≡ 401 × 401 ≡ 160,801 ≡ 801 716 ≡ 78 × 78 ≡ 801 × 801 ≡ 640,601 ≡ 601 a = 7, b = 16 Input 以下、法を1000とする 繰り返し2乗することで 𝒂𝒂𝒃𝒃を 𝒌𝒌 回の掛け算で求められる
  13. 問題点②の解決策(𝒃𝒃 ≠ 𝟐𝟐𝒌𝒌 のとき) a = 7, b = 21

    Input 以下、法を1000とする 721 ≡ 716 × 74 × 71 ≡ 601 × 401 × 7 ≡ 1,687,007 ≡ 7 𝒃𝒃 = 𝟐𝟐𝒌𝒌のときの結果を利用することで答えを高速に求められる 71 ≡ 7 72 ≡ 71 × 71 ≡ 49 74 ≡ 72 × 72 ≡ 401 78 ≡ 74 × 74 ≡ 801 716 ≡ 78 × 78 ≡ 601 16 8 4 2 1 1 0 1 0 1 𝟐𝟐𝟐𝟐 = 𝟏𝟏𝟏𝟏𝟏𝟏𝟏𝟏𝟏𝟏(𝟐𝟐) bを2進法で表すと bの作り方が分かる
  14. 問題点②の解決策 𝟏𝟏 ≤ 𝒃𝒃 ≤ 𝟏𝟏𝟎𝟎𝟏𝟏𝟏𝟏 < 𝟐𝟐𝟔𝟔𝟔𝟔 なので 𝒌𝒌

    = 𝟔𝟔𝟔𝟔 まで計算しておけばOK 数十から数百回の計算で答えを求められるので 0.1秒以内にはプログラムが終了する Pythonでの実装を見てみよう DEMO
  15. 本問題のまとめ 71 72 74 78 716 • 「1つ先→2つ先→4つ先→… 」のようにどんどんと倍を求めて 高速化するアルゴリズムを”ダブリング”という

    • その中でも今回紹介したものを特別に”繰り返し二乗法”という • 名前の付いたアルゴリズムを知ることで 発想が難しいアルゴリズムを構築する足掛かりになる
  16. 幅優先探索 深さ優先探索 二分探索 Euler Tour Binary Indexed Tree Dynamic Programming

    Rolling Hash Segment Tree Dijkstra's algorithm Bostan-Mori 法 Monotone minim kd Tree 累積和 Low link owest Common Ancestor Minimum-cost Flow Slope Trick 2-SAT G 600pt 問題 F 525pt 問題 E 500pt 問題 D 400pt 問題 B 200pt 問題 A 100pt 問題 C 350pt 問題 まだまだ広がる競技プログラミングの世界
  17. 競技プログラミングを 始めたいと思ったら • まずはAtCoderのアカウントを作成する • AtCoder Problems から過去問を解いてみる • ABC

    の日程を確認して参加する • 競技プログラミングの入門書を読む(図書館にも蔵書有) • HUITで競技プログラミングをやっている人に話を聞く • (プログラミングをやったことがない人はこちらから) C++入門 AtCoder Programming Guide for beginners (APG4b)