Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 7811

ABC381挑戦記(D問題まで) - JunKobayashi’s diary

$
0
0

金曜日に差し込まれるというなかなかの苦痛を味わうもなんとか4完で耐えていく。本番ACには至らなかったが、前回のD問題と比較すると圧倒的に理解しやすかったためE問題は是非とも取りたかった・・・。

※特に断らない限り、0-indexedを前提に記載する。

 

<A問題>

↓問題のページ↓

A - 11/22 String

 

問題文で示されている各条件を全て満たしているかを愚直に1つずつ判定しよう。即ち、長さが奇数、真ん中の文字が'/'、前半部分・後半部分はそれぞれ'1'・'2'のみで構成されているかどうかを確認してAC獲得(150点が与えられているだけありA問題にしては少し難しめだった)。

 

<B問題>

↓問題のページ↓

B - 1122 String

 

扱う対象が変わっただけで本質的にはA問題とさして変わらない。長さが偶数、隣り合う2文字は同じ、各文字はちょうど2回ずつのみ現れるという3つの条件が全て満たされているかを愚直に判定してAC獲得。

 

<C問題>

↓問題のページ↓

C - 11/22 Substring

 

ぱっと見では結構難しそうに感じたがなんとか本番AC成功。やり方はいろいろあるだろうが、ランレングス圧縮を使うのが簡便だと個人的には感じる。以下、\(S\)をランレングス圧縮した結果を\(U\)(その要素数を\(M\))とし、\(U\)の\(x\)番目の要素を\(C_x , L_x \)とする(それぞれ繰り返される文字と繰り返し回数を表す)。答えを表す変数\(ans\)を\(1\)で初期化しておき(\(S\)は文字'/'を必ず1個以上含むという制約があるため)、\(i = 1, 2, \dotsc , M - 2\)について、\(U_{i - 1}, U_i, U_{i + 1}\)それぞれの文字要素が'1'・'/'・'2'で、且つ\(U_{i}\)の長さ要素が\(1\)の場合に\begin{align} ans = \max (ans, 1 + \min (L_{i - 1} , L_{i + 1})) \end{align}というように更新していくと良い。この解法は\(\mathcal{O}(N)\)で動き十分高速である。

 

<D問題>

↓問題のページ↓

D - 1122 Substring

 

考察を詰め切るのが結構難しく、WAの解消に苦労した。C問題と同じくランレングス圧縮(扱うのは文字列ではなく数列だが本質的に大差ないためこの呼び方を選ぶ)を使うのが解きやすいように思えた。以下、\(A\)をランレングス圧縮した結果を\(B\)(その要素数を\(M\))とし、\(B\)の\(x\)番目の要素を\(V_x , L_x \)とする(それぞれ繰り返される値と繰り返し回数を表す)。C問題と違って、1122数列であるための条件を全て満たす長さ\(2\)以上の連続部分列が存在する入力しか与えられないという制約はないため答えを表す変数\(ans\)を\(0\)で初期化する。

これと尺取り法を用いることで、この問題を\(\mathcal{O}(N)\)という十分な速さで解くことができる。\(l = r = 0\)と初期化するとともにその時点までに1122文字列の要素として使用している整数値を覚えておく集合\(S\)を用意しておき、以下の考察に従って実装していくと良い。

1)\(L_r = 1\)の場合、\(B_r\)を1122文字列の構成要素にはできないので\(ans\)を\(S\)の要素数に\(2\)を掛けた値で更新し、\(r\)をインクリメントして\(l\)を\(r\)の値で更新し、\(S\)を空の状態にする。

2)\(l = r\)の場合は特殊であり、\(L_r = 2\)だけでなく\(L_r \geq 3\)である場合にも末尾の2個だけを取り出せば1122文字列の構成要素として適切なので、\(S\)に\(V_r\)を追加して\(r\)をインクリメントする。

3)\(V_r\)が\(S\)に含まれる場合は\(L_r \geq 3\)か\(L_r = 2\)かで扱いが変わる。前者の場合、1)と同様に\(ans, S\)を更新し、\(l = r\)と更新する。後者の場合は\(B_r\)を1122文字列の構成要素として選び取る場合の方がより長くできる可能性がまだ残されているため、1)と同様に\(ans\)を更新したのちに\(l\)をインクリメント、\(S\)から\(V_l \)を削除というようにしていく。

4)\(V_r\)が\(S\)に含まれない場合も\(L_r \geq 3\)か\(L_r = 2\)かで扱いが変わる。前者の場合、\(V_r\)のうち先頭の2つのみを取り出せばそれは1122文字列の構成要素として適切であるから、\(S\)に\(V_r\)を追加した後、3)と同様に\(ans, S, l\)を更新する。後者の場合は単に\(V_r\)を\(S\)に追加し、\(r\)をインクリメントする。

※\(r = M\)に達したら1)と同様に\(ans\)を更新したのちに上記の反復を抜け出す。


Viewing all articles
Browse latest Browse all 7811

Trending Articles