More Related Content
More from AtCoder Inc. (20)
CODE FESTIVAL 予選B 解説
- 3. A問題
• 問題概要
– 2つの整数A,Bが与えられる。
– 大きい方を出力してください。
• 解説
– 比較演算子とif文を使って場合分けする
– 諸言語で予め実装されているmax関数等を使う
2014/10/26 3
- 5. B問題問題概要
• 要素数Nの数列Aが与えられる。
• A[ 1]~A[i]の総和がKを超える最小のiを求めよ。
• 制約
– 1 ≦ N ≦ 100,000
– 1 ≦ A[i] ≦ 100,000
– 1 ≦ K ≦ 1,000,000,000
2014/10/26 5
- 8. C問題問題概要
• 2N( Nは整数) 文字の文字列S1, S2,S3がある
• S1の半分とS2の半分を取ってきて並び替えることで
S3が構成可能か判断せよ。
• 制約
– 2 ≦ 2 N ≦ 100,000
– S1,S2,S3は大文字アルファベットのみから構成される
2014/10/26 8
- 9. C問題アルゴリズム
• 構成する際に並び替えることができるので、S1,S2,S3
の文字列の順番は答えに影響しない
– 各アルファベットを何個ずつ含むかだけが必要
• まずはN文字ずつ取り出すという制約を無視する
– 取り出し方をアルファベットごとに独立して考えることが出
来る
– 例えば「'A'をS1から何個取り出すか」と「'B'をS1から何個
取り出すか」は全く影響しあわない
2014/10/26 9
- 10. C問題アルゴリズム
• 各アルファベットについてS1から取り出すことが出
来る文字数の範囲を求める
• S1から取り出す文字数が少なすぎると、S2から取り
出す文字数にかかわらず、S3を構成するのに足り
なくなる
– 例:S1='AABB' S2='AAAB' S3='ABBB'のときS1から' B 'を
1つしか取り出さないとすると、S3を構成できなくなる
2014/10/26 10
- 11. C問題アルゴリズム
• 各アルファベットについてS1から取り出すことが出
来る文字数の範囲を求める
• S1から取り出す文字数が多すぎると、S2から取り出
す文字数にかかわらず、S3を構成するのに余ってし
まう
– 例:S1=‘AAAB’ S2=‘AABB’ S3=‘ABBB’のときS1から
‘ A’を3つも取り出すとすると、S3を構成するのに余って
しまう
2014/10/26 11
- 12. C問題アルゴリズム
• 各アルファベットについてS1から取り出すことが出
来る文字数の範囲を求める
• あるアルファベットがS1,S2,S3にそれぞれC1,C2,C3
文字ずつ含まれていたとすると、S1から取り出すこ
とが出来る文字数の範囲は
– max(0, C3-C2) ~ min(C1, C3)
– この間の値は全てとれる
2014/10/26 12
- 13. C問題アルゴリズム
• 各アルファベットについてこの範囲をもとめて、うまく
総和がN/2にすることが出来るか判断すれば良い
• できるだけ少なくS1から取り出した時の文字数と、で
きるだけ多くS1から取り出した時の文字数の間に
N/2があるかどうか判断する。
– それぞれさきほどのmax(0,. C3-C2) ~ min(C1, C3) の
総和を取れば求めることが出来る
2014/10/26 13
- 15. D問題問題概要
• 要素数Nの数列Aが与えられる。
• 各i( 1≦i≦N)に対してiとjの間の全てのk( jも含む)に
ついてA[k]≦ A[ i]であるようなjの個数を求めよ。
• 制約
– 1≦N≦ 100,000
– 1≦A[i]≦100,000
2014/10/26 15
- 19. D問題アルゴリズム
• 山小屋iから見える範囲
• これはiを含むある区間である
• iに一番近いh[i]より高い山小屋が両端となる
• 両端をどう求めるか?
– 全探索
– DP
– stackをつかう
– 二分探索
2014/10/26 19
- 20. D問題アルゴリズム
• 山小屋iから見える範囲
• これはiを含むある区間である
• iに一番近いh[i]より高い山小屋が両端となる
• 両端をどう求めるか?
– 全探索
– DP
– stackをつかう
– 二分探索
2014/10/26 20
- 29. D問題アルゴリズム
• 山小屋iから見える範囲
• これはiを含むある区間である
• iに一番近いh[i]より高い山小屋が両端となる
• 両端をどう求めるか?
– 全探索
– DP
– stackをつかう
– 二分探索
2014/10/26 29
- 53. D問題アルゴリズム
• dp[i] = dp[dp[i]]という操作を最悪でO(N)回するので
総計算量はO(N^2)?
– 実はO(N)
• dp[i] = dp[dp[i]]という操作(先ほどの例では黒い矢
印をたどること)は各矢印についてたかだか1回しか
行われない
– 矢印はO(N)個しかないので総計算量はO(N)
• 満点が得られる
2014/10/26 53
- 54. D問題アルゴリズム
• dp[i] = dp[dp[i]]という操作を最悪でO(N)回するので
総計算量はO(N^2)?
– 実はO(N)
• dp[i] = dp[dp[i]]という操作(先ほどの例では黒い矢
印をたどること)は各矢印についてたかだか1回しか
行われない
– 矢印はO(N)個しかないので総計算量はO(N)
• 満点が得られる
2014/10/26 54
- 55. D問題アルゴリズム
• 山小屋iから見える範囲
• これはiを含むある区間である
• iに一番近いh[i]より高い山小屋が両端となる
• 両端をどう求めるか?
– 全探索
– DP
– stackをつかう
– 二分探索
2014/10/26 55
- 56. D問題アルゴリズム
• stackを用意する
• 東から順番に
– h[i] がh[ stackの先頭]より大きい限りstackの先頭をpop
し続ける
– dp[ i] = stackの先頭
– iをstackの先頭にpushする
• というふうにやると先ほどと同じdp[i]が得られる
• 実質やっていることはDP解と同じ
– こちらのほうがO(N)であることがわかりやすい
2014/10/26 56
- 57. D問題アルゴリズム
• 山小屋iから見える範囲
• これはiを含むある区間である
• iに一番近いh[i]より高い山小屋が両端となる
• 両端をどう求めるか?
– 全探索
– DP
– stackをつかう
– 二分探索
2014/10/26 57
- 71. D問題アルゴリズム
• この解法を思いつく人が一番多いと予想される
• しかし、挿入と探索が効率的にできるデータ構造を
実装するのはコンテスト時間内では慣れていないと
難しい
– set等が予め用意されていない言語だと、この解法は実装
しづらい
– そういう時は先程のDPやstackを使った解法を実装すれ
ば良い
2014/10/26 71