AtCoderのA-Irreversible operation解いたメモ

beta.atcoder.jp

競プロn度目の入門ということで、タイトルの問題を解いてみた。
自分には難しく感じたけど、スコア設定的にたぶん簡単な問題ということなんだろうと思う。

まだ解説が出ていないみたいなので自分なりに解説してみる。

最初に思いついたのは「石をひっくり返すcountを取りつつ実際にstringを作っていく」というものだったけど、
これではConstraintsの2 * 105の長さのSを扱うことができない。

自分の解法を言うと

Sを先頭から順番に見ていき、
対象がWだった場合には
出てきたWのカウントを + 1して、
その時点でのindex + 1から、それまでのWのカウントを引いたものをカウントに加える

というもの。

文字にすると説明が難しいが、

例えば

BBW

の場合、Wが出てくる時点でのindexは2、
Wのカウントは1なので、
3 - 1がcountになるので答えは2となる。

なぜこうなるのかは実際にflipする様子を紙などに書いていくと理解できると思う。

BBW
BWB ... flip 1
WBB ... flip 2

Wが左にBの個数分移動している。ここから自分自身(W)の数を引けばflipの回数と一致する。

Wが複数出てくる場合も考え方は同じで

BWBWBW

なら、

Wが出てくるたびに上記の計算結果をcountに足せば良い。

ループ一回で済むので O(n) で解くことができる

s = gets.chomp
 
count = 0
w_count = 0
 
s.chars.each.with_index(1) do |char, i|
  if char == "W"
    w_count += 1
    count += i - w_count
  end
end
 
puts count