CODE THANKS FESTIVAL 2014 A日程 解説 
AtCoder株式会社 代表取締役 
高橋 直大 
2014/12/12 
1
©AtCoder Inc. All rights reserved. 
2 
A問題 カメツル算 
2014/12/12
A問題 問題概要 
•カメがA匹、ツルがB羽います。 
•足の本数を求めなさい。 
•制約 
• 1≦A, B≦1000 
2014/12/12 
3
A問題 アルゴリズム 
•A×4+B×2を出力しよう! 
–罠とかは何もないです! 
2014/12/12 
4
©AtCoder Inc. All rights reserved. 
5 
B問題 バッジ 
2014/12/12
B問題 概要 
•バッジを N 個作りたいです。 
•3 つの機械(ちょうど 1 分経つとバッジを作る)を順繰 りに動かすことができます。 
•動かす順番をうまく決めたときに、N 個作るまでにか かる時間の最小値を求めてください。 
•1 ≦ N ≦ 1,000 
•1 ≦ A ≦ 1,000 
•1 ≦ B ≦ 1,000 
•1 ≦ C ≦ 1,000
B問題 全探索による解法 
•機械の動かす順番は 
A→B→C→A→… A→C→B→A→… 
B→A→C→B→… B→C→A→B→… 
C→A→B→C→… C→B→A→C→… 
の 6 通りあります。 
•すべての組み合わせを試して、一番短い時間で出 来たものを答えとして出力します。
B問題 貪欲法による解法 
•実は最初の 3 回は、生産量の多い機械を優先して 作るように決めても最適解が出ます。 
•なぜなら、かかった時間 t について、t の値が 
3 の倍数+0 ⇒ すべての機械が同じだけ動くのでど の順でも一緒 
3 の倍数+1 ⇒ 最初 1 つだけ多く動くので先頭の生 産量が多いと得 
3 の倍数+2 ⇒ 最後以外多く動くので先頭 2 つの生 産量が多いと得 
となるからです。
©AtCoder Inc. All rights reserved. 
9 
C問題 コンテスト 
2014/12/12
C問題 問題概要 
•N問のコンテストがあり、M問の問題が解けた。 
•問題の配点と、解けた問題が与えられる。 
•得られた得点を出力しなさい。 
2014/12/12 
10
C問題 アルゴリズム 
•配点と解けた問題が与えられるので、素直に解けた 問題に対応する点数を足し算していけば良い 
•1-indexedなので、配列にそのまま入れると1つずれ ていることに注意! 
2014/12/12 
11
©AtCoder Inc. All rights reserved. 
12 
D問題 定期券 
2014/12/12
D問題 問題概要 
•1 駅ごとに 100 円の運賃がかかる路線がある 
•定期券の圏内の移動分には運賃がかからない 
•駅 a から駅 b への定期券を持っている人が 
•駅 s から駅 t へ行くときにかかる運賃は? 
2014/12/12 
13
D問題 問題概要 
•1 駅ごとに 100 円の運賃がかかる路線がある 
•定期券の圏内の移動分には運賃がかからない 
•駅 a から駅 b への定期券を持っている人が 
•駅 s から駅 t へ行くときにかかる運賃は? 
–この質問が 105 回来る → 高速に答える必要あり 
2014/12/12 
14
D問題 アルゴリズム 
•基本的には (t - s) × 100 円かかる 
•そこから定期券の範囲と被っている部分を引く 
2014/12/12 
15
D問題 アルゴリズム 
•区間の共通部分の計算をしたい 
•min(b, t) - max(a, s) が共通部分の長さ 
2014/12/12 
16
D問題 アルゴリズム 
•min(b, t) - max(a, s) が負のときは共通部分なし 
•0 との max をとれば OK 
2014/12/12 
17
©AtCoder Inc. All rights reserved. 
18 
E問題 儀式 
2014/12/12
E問題 概要 
•縦 R 行、横 C 列の各マスに南向きの石像がある。 
•区間を指定して、90 度左に回転させる動作を N 回 行う。 
•1 回だけ忘れた結果、南向きの石像が M 個になっ た。 
•忘れた操作として考えられるものを昇順に出力せよ。 
•1 ≦ R ≦ 50 
•1 ≦ C ≦ 50 
•1 ≦ N ≦ 5,000
E問題 すべての可能性を試す場合 
•N 個の操作それぞれについて、残り N – 1 個の操作 を順に実行してみた場合を考えると、計算量が O(RCN2) となってしまいます。 
•ほとんど同じ操作を行っているのでうまくまとめて処 理したいです。
E問題 考察 
•各手順 [S1][S2]…[SN] は可換です。 
•そのため、各 [Si] について、その領域を右に 90 度 回転させる(逆の操作をする)操作を [Ti] とおくと、 
[S1][S2]…[S(i-1)][S(i+1)][S(i+2)]…[SN] 
=( [S1][S2]…[S(i-1)][S(i+1)][S(i+2)]…[SN] ) ( [Si][Ti] ) 
= [S1][S2]…[SN][Ti] 
が成り立ちます。
E問題 解法 
•最初に D=[S1][S2]…[SN] の結果を求めておきます。 
•各 i に対して、 [S1][S2]…[SN][Ti](=D[Ti]) の結果を求 め、南向きの石像がいくつあるか数えます。 
•その個数がちょうど M 個ならば手順 i は解となりま す。 
•計算量は O(RCN) となります。
E問題 その他の解法 
•ある連続する番号[a,b] について、a 番目の手順から b 番目の手順までをすべて実行したときにそれぞれ の石像が90度回転する回数を計算するには、 segment-tree を用いることで実現できます。 
•各 i について、[1,i-1] と [i+1,N] の作用を segment- tree で計算することで、全体で O(RCNlogN) で計算 できます。
©AtCoder Inc. All rights reserved. 
24 
F問題 順位表 
2014/12/12
F問題 問題概要 
•コンテスト参加者の人数Nと、「誰が誰より順位が上 だった」というM個の情報が与えらる 
•高橋君(参加者1)の順位として、考えられる最も高 い順位を出力しなさい 
•1≦N, M≦50 
2014/12/12 
25
F問題 考察 
•具体例を考えてみる 
–上に繋がっているのが順位が上 
2014/12/12 
26
F問題 考察 
•具体例を考えてみる 
–上に繋がっているのが順位が上 
–直接上に繋がっているところは 
順位が上 
2014/12/12 
27
F問題 考察 
•具体例を考えてみる 
–上に繋がっているのが順位が上 
–直接上に繋がっているところは 
順位が上 
–そこから上に繋がるものも上 
2014/12/12 
28
F問題 考察 
•具体例を考えてみる 
–上に繋がっているのが順位が上 
–直接上に繋がっているところは 
順位が上 
–そこから上に繋がるものも上 
–上に行くだけで辿り着けない 
人は、順位が上か不明 
–繋がっていないところも不明 
2014/12/12 
29 
? 
? 
? 
? 
? 
? 
? 
?
F問題 考察 
•具体例を考えてみる 
–上に繋がっているのが順位が上 
–直接上に繋がっているところは 
順位が上 
–そこから上に繋がるものも上 
–上に行くだけで辿り着けない 
人は、順位が上か不明 
–繋がっていないところも不明 
–繋がっていないところは 
全部自分より下な場合もある! 
2014/12/12 
30 
? 
? 
? 
? 
? 
? 
? 
?
F問題 アルゴリズム 
•先ほどの考察により、「上にだけ移動することにより 到達可能な人」のみを、自分より上の順位だとすれ ば良い。 
•これは、深さ優先探索や、幅優先探索などの、単純 な探索で求めることが出来る。 
•計算量はO(N + M) 
2014/12/12 
31
©AtCoder Inc. All rights reserved. 
32 
G問題 通勤電車と気分 
2014/12/12
G問題 問題概要 
•N 人の人が K 個の席 (1~K) に座っていく 
•それぞれの人が席を選ぶ戦略は 2 通り 
–戦略A: 空席のうち番号が最も小さいものに座る 
–戦略B: 空席で、両隣も空席であるもののうち番号が最も 小さいものに座る 
•i 人目の人は pi %の確率で戦略 A を、100 - pi %の 確率で戦略 B をとる。 
•N 人目までが席を選び終えたとき、空席の個数の期 待値を求めよ。 
2014/12/12 
33
G問題 全探索? 
•それぞれの人の気分を全部試す (2^N 通り) 
•気分が決まればその確率がわかり、席の状態はシ ミュレーションすれば決まる。 
•TLE (部分点の 30 点はとれる) 
2014/12/12 
34
G問題 戦略を観察 
2014/12/12 
35
G問題 戦略を観察 
2014/12/12 
36
G問題 戦略を観察 
2014/12/12 
37
G問題 戦略を観察 
2014/12/12 
38
G問題 DP (動的計画法) 
•dp[n][i][j] := 人 n までが席を選び終わったとき、 
–人のいる席のうち最も番号が大きいのは席 i で 
–席 1 ~ 席 i - 1 のうち j 個が空席 
•となっている確率 
として、これを計算していく 
2014/12/12 
39
G問題 席の状態の遷移 (戦略A) 
2014/12/12 
40
G問題 席の状態の遷移 (戦略B) 
2014/12/12 
41
G問題 計算量 
•席の状態は全部で O(NK^2) 通り 
•遷移は戦略 A, B の 2 通り 
•全体で計算量は O(NK^2) 
•100 点 
2014/12/12 
42
©AtCoder Inc. All rights reserved. 
43 
H問題 模様替え 
2014/12/12
概要 
•縦 R 行、横 C 列の各マスに文字列が書かれている。 
•2 * 2 以上の領域で、点対称な形になっているもの の総数を求めよ。 
•1 ≦ R ≦ 250 
•1 ≦ C ≦ 250 
•条件を満たす例(入力例1より) 
c 
o 
d 
d 
o 
c 
k 
s 
s 
k
部分点解法1 
•取り出す領域の左上と右下を固定し、1 つ 1 つ比較 して実際にうまくいくかを試す。 
•候補が O(R2C2) 個あり、それぞれの検証にO(RC) かかるので、全体で O(R3C3) かかる。 
•R および C が 20 以下なら解ける。 
α 
β 
γ 
δ 
ε 
ζ 
ζ 
ε 
δ 
γ 
β 
α 
記号が同じ場所をチェックす る。
文字列の比較の高速化(1/3) 
•文字列の比較部分を高速化できないだろうか? 
•点対称かどうかを判定する際に 1 文字 1 文字判定 するのではなく、文字列としてまとめて判定したい! 
•点対称というのは、上側を左から右に読んだものと、 下側を右から左(上側の場合とは逆向き)に読んだも のとが等しいということをうまく使えそう! 
α 
β 
γ 
δ 
ε 
ζ 
ζ 
ε 
δ 
γ 
β 
α 
どちらもαβγδになってい る!
文字列の比較の高速化(2/3) 
•文字列の比較には、ローリングハッシュという手法 を用いることで高速に比較することができます。 
•具体例としては、定数 X と mod する数 M を決めて おいて、文字列 S のハッシュ値 H を H′= str の 푖 文字目を表す整数∗X푖−1 |str| 푖=1 とし たとき、H′ を M で割った余りと定めます。 
•例えば、X= 10 , M = 999で、各文字を表す整数をア ルファベットの順番としたとき、文字列 abcd のハッ シュ値は H′=1∗100+2∗101+3∗102+4∗ 103(=4321)から H=325 (325=4321-999*4) となりま す。
文字列の比較の高速化(3/3) 
•ハッシュ値が異なる文字列同士は、確実に違う文字列と 言えます。 
•ハッシュ値が同じ場合は、同じ文字列である可能性があ ります。 
•理論上は異なる文字列同士のハッシュ値が衝突する場 合があり、100% 同じ文字列であるという保証はありませ んが、M をでかくとる、複数のハッシュ値を試す、などの 対策をとっておけば高めの確率で衝突を回避できます。 
•ある区間[a,b]のハッシュ値H([a,b])は、 
H([a,末端])-H([b,末端])*X(区間[푎,푏]の要素数)で計算でき ます。
ローリングハッシュを用いた場合 
•先ほどの比較で各文字ごとに比較していたものが、 各列ごとの比較で済むようになり、次数が 1 つ減り、 5 乗オーダーとなります。 
•今回の場合は 5 乗だと時間制限に間に合わない可 能性があります。 
•そのため、次に 4 乗にする方針を考えます。 
•方針1: 文字列ではなく、長方形領域に関するローリ ングハッシュを用いる。 
•方針2: DP を用いる。
部分点解法2 - 方針 1 の場合 
•H′= str の 푖 文字目を表す整数∗X푖−1 |str| 푖=1 という式を変形し て、 
H′= 区間の 푖 行目の左から 푗 文字目を表す整数∗X푖−1∗Y푖−1 푖,푗 
のような変形をして全体同士の比較をすれば、全体で O(R2C2) で動 作します。 
•実装に関しては2次元の累積和を求めるようにたし引きします。 
H([a,b]*[c,d]) = H([a,末端]*[c,末端]) 
-H([b+1,末端]*[c,末端])*(累乗) 
-H([a,末端]*[d+1,末端])*(累乗) 
+H([b+1,末端]*[d+1,末端])*(累乗)
部分点解法2 - 方針 2 の場合 
•外側の比較を行い、内側はより小さケースの結果を メモしたものを使用することで、文字列のハッシュで O(R2C2) で実現できます。 
•この場合、メモリ制限に注意してください。 
外周部をローリング ハッシュで、内側は 先に計算した結果を 利用
さらなる高速化 
•これよりも早くする場合、答えの個数が O(R2C2) 個 あることから、複数の解をまとめて数え上げるような 方針が必要となります。 
•中心を固定して考えることにします。 
(以降の説明では中心が特定のマスの中央にある場 合について考えていますが、他の場合も同様です。)
考察(1/3) 
•ある領域で点対称だとすると、その領域の横幅を縮 めても中心が同じなら同様に点対称となる。 
•高さを固定して、その中で最も左にある(横幅の大き い)ものを求めれば、それより右の部分は確かめなく ても数え上げることができる。 
中心
考察(2/3) 
•最も左にある(横幅の大きい)状態から、縦幅を大き くすると、横幅は短くなる場合はあるものの、長くな る場合はない(前の段階でもっと横幅を大きく取れる ことになり矛盾)。 
中心
考察(3/3) 
•以上 2 点をまとめると、下図のようにうねうね遷移す るしゃくとり法が出てくる。 
→ 
→ 
→ 
↑ 
→ 
↑ 
→ 
↑ 
↑ 
→ 
→ 
↑ 
↑ 
(中 心)
しゃくとり法詳細 
•縦幅最小で横幅最大の状態からスタート。 
•点対称となるまで、上側端と下側端のみについて比 較し(それ以外は既に点対称だとわかっている)、失 敗したら横幅を短くする。 
•点対称となったら、そのときの幅から、中心と高さが 定まった場合の点対称なデザインの個数がわかる ので、これを答えに加算して縦幅を大きくしてまた横 に比較する。を繰り返す。 
•横幅が 0 になったり、外部にはみ出したら終了。 
•これをすべての中心について試す。
満点解法 
•先ほどのしゃくとりをすべての中心について試す。 
•中心の候補は O(RC) あり、各しゃくとりでO(R+C) かかるので、全体で O(RC(R+C)) となる。
備考 
•ローリングハッシュを使用しなくても、接尾辞配列を 用いることでも同じことができます。 
•こちらの場合は衝突による間違いがありませんが、 実装や計算量が異なり、制限時間に注意する必要 があります。
©AtCoder Inc. All rights reserved. 
59 
おわり! 
2014/12/12

CODE THANKS FESTIVAL 2014 A日程 解説