Rust で始める
競技プログラミング
minaminao
roppongi.rs #2
岡南 直哉
minaminao
@vinami
自己紹介
筑波大学 情報学群 情報科学類 4年
2019/07 LayerX R&D チーム
1. 競プロとは
2. 得られるもの
3. 100点問題
目次
4. 200点問題
5. 300点問題
6. まとめ
競技プログラミングとは
1. 問題が与えられる
・実行時間とメモリ使用量の上限付き
2. それを解くプログラムを実装&提出
3. サーバーが正解か判定
解けた問題数が多い方が勝ち
競プロで得られるもの
・プログラミング言語の知識と実装力
・問題解決力、論理的思考力、数学力
・高速なプログラムの実装方法
- アルゴリズムとデータ構造
アルゴリズムとデータ構造
組合せ数学、包除原理、分割数、セグメントツリー、平方分割、ヒープ、Binary
Indexed Tree、平衡二分探索木、座標圧縮、k-d木、Union-Find、動的最適化、ゲー
ム理論、最長増加部分列、巡回セールスマン問題、最小包含球、幾何、最小重み三角
形分割、グラフ理論、最短経路問題、木、Lowest Common Ancestor、マッチング、
閉路検出、彩色数、Low-link、最小全域木、トポロジカルソート、強連結成分分解、
貪欲法、線形代数、ガウスの消去法、数論、二項係数、GCD/LCM、素因数分解、
数値解析、二分法、ラグランジュ補間、ソート、転倒数、Manacher、Morris‒Pratt、
ローリングハッシュ、Suffix Array、Z Algorithm、しゃくとり法、等
これら(一例)を理解&使えるようになる
早速やってみる
Rustで!
ABC086 A - Product
https://atcoder.jp/contests/abc086/tasks/abc086_a
ABC086 A - Product (100点)
•正整数a,bが標準入力から与えられる
•空白区切り
•a*bが偶数ならEvenを奇数ならOddを出力
•a, b <= 10000
問題概要
•標準入力を使う: use std::io;
•偶数かどうか: if (a * b) % 2 == 0
ポイント
ABC086 A - Product (100点)
• https://atcoder.jp/contests/abc086/submissions/7563758
解答例
ABC086 A - Product - 解答例
ABC086 A - Product - 解答例
入力を楽にしたい!
空白・改行ごとに入力を得る関数
空白・改行ごとに入力を得る関数
• Rustで競技プログラミングの入力をスッキリ記述するマクロ - Qiita (by たなこふさん)
• https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
更に高機能な入力補助
わかりやすい
ABC080 A - Parking
https://atcoder.jp/contests/abc080/tasks/abc080_a
ABC086 A - Product (100点)
•駐車場の料金プランが2種類
•プラン1: T時間でA*T円
•プラン2: B円固定
•正整数N,A,Bが与えられる
•N時間駐車するときの最安の値段は?
問題概要
•min関数 use std::cmp::min;
•min(a,b)
ポイント
ABC086 A - Product (100点)
代表的コンテストサイト
AtCoder Codeforces
Google
Code Jam
開催頻度 1,2回/週 6回くらい/月 1回/年
参加人数/回 約5000人 約10000人 約35000人
開催国 日本 ロシア -
問題文 日本語 / 英語 英語 英語
Rust version 1.15.1 1.35.0 未対応
点数
点数 レベル
100 四則演算, 文字列操作
200 条件分岐, ループ
300 ソートなどのアルゴリズムの知識が必要に
400 ~
計算量の見積もりが必要に
2000点以上の問題も
ABC086 B - 1 21
https://atcoder.jp/contests/abc086/tasks/abc086_b
ABC086 B - 1 21 (200点)
•正整数a,bが標準入力から与えられる
•空白区切り
•aとbを文字列として繋げたとき平方数か?
•例. 1 21 は 121 = 11^2
•平方数ならYes、そうでないならNoを出力
•a, b <= 100
問題概要
•文字列結合: format!( {}{} ,a,b)
•String to isize: s.parse::<isize>().unwrap()
ポイント
ABC086 B - 1 21 (200点)
• x := aとbを結合した数値
• i=1 x まで i*i == x を満たすものが存在するか調べる
• 存在するならxは平方数
解答例
ABC086 B - 1 21 - 解答例
この解法の計算量はO(x)
更に良い解法
・i=1 xで探索 O( x)
・iについて二分探索 O(log x)
計算量 例 1秒以内で
O(1) 四則演算など -
O(n) n=約10^8まで
O(n^2) n=約10^4まで
O(log n) 二分探索など たくさん
O(n log n) ソートなど n=約10^5まで
計算量
•O(n) : n回計算するならO(n)
•定数倍は無視 2n回計算するとしてもO(n)
Big O 記法
ABC063 B - Varied
https://atcoder.jp/contests/abc063/tasks/abc063_b
ABC063 B - Varied (200点)
•英小文字からなる文字列Sが与えられる
•Sに含まれる文字が全て異なるかどうか
•異なるならyes、そうでないならnoを出力
•Sの長さ <= 26
問題概要
ABC063 B - Varied - 解答例
•String は s[i] のように文字の取得ができない
•String から Vec<char> に変換する
ポイント
ABC127 C - Prison
https://atcoder.jp/contests/abc127/tasks/abc127_c
ABC127 C - Prison (300点)
•N枚のIDカード, M枚のゲート
•ゲートはIDカードで通れる
•i番目のゲートは L_i R_i 番目のIDカードで通れる
•どれか1つ持っていればいい
•1枚だけで全ゲートを通過できるIDカードは何枚か
•N <= 10^5, M <= 10^5
•1 <= L_i <= R_i <= N
問題概要
Sample 1
ID1 ID2 ID3 ID4
G1
G2
N=4 M=2
(L_1, R_1) = (1, 3)
(L_2, R_2) = (2, 4)
2番目と3番目のIDカードが全ゲートを通れる
Sample 2
ID1 2 3 4 5 6 7 8 9 10
G1
G2
G3
6番目のIDカードのみ全ゲートを通れる
ABC127 C - Prison - 解答例
ABC127 C - Otoshidama
https://atcoder.jp/contests/abc085/tasks/abc085_c
ABC127 C - Otoshidama (300点)
•10000円札、5000円札、1000円札が無限にある
•お札がN枚、合計Y円
•10000円札x枚、5000円札y枚、1000円札z枚とする
•有り得る枚数の組合せ1つを出力
•Y=28000円なら、(x,y,z) = (2,1,3) など
問題概要
TLE解答
TLE解答 O(n^3)
n^3=8*10^9 間に合わない
AC解答 O(n^2)
まとめ
まとめ
•圧倒的アウトプットができる
•計算量が見積もれるようになる
•アルゴリズムとデータ構造に詳しくなれる
•実力が定量化される
•何より楽しい
•実行に100年かかる処理が1秒でできたり
•日に日にコーディングスピードが速くなったり
おまけ(ojによる自動提出)
https://github.com/minaminao/atcoder-rust/blob/master/.vscode/tasks.json
https://github.com/kmyk/online-judge-tools

Rustで始める競技プログラミング