Official

B - 1D Akari Editorial by sounansya


問題の条件を整理すると、条件は直感的には以下のように捉えることができます。

  • \(S\) のいくつかの .o に置き換える。
  • ただし、\(2\) つの o の間には # がある必要がある。
  • この条件下の中で o の文字数を最大にしたい。

ここで、「\(2\) つの o の間には # がある必要がある」という条件から「いくつかの連続する . の中で o に置き換えられる文字は \(1\) つまで」ということが分かります。たとえば \(S=\) ...#.. であったとき、左側の連続する ... 、右側の連続する .. の中で o に置き換えられる文字はそれぞれ \(1\) 文字ずつまで、ということです。

この条件を満たすように \(T\) を構成する方法はいくつかありますが、ここでは追加で「o に置き換える文字はできるだけ左側の文字にする」という条件を考えてみます。たとえば \(S=\) ...#.. の場合は \(T=\) o..#o. のように、できるだけ左の文字を置き換えるということです。

すると、 \(T\)\(1\) 文字目以外は #. となる場所を #o に置き換えれば良いことが分かります。 \(T\)\(1\) 文字目も \(S\)\(0\) 文字目に仮想的な # が存在すると考えることで場合分けを減らすことができます。

実装例(Python3)

print(("#"+input()).replace("#.","#o")[1:])

実装例(C++)

#include <bits/stdc++.h>
using namespace std;

int main() {
	string s;
	cin >> s;
	int n = s.size();
	vector<char> t(n);
	for (int i = 0; i < n; i++) {
		if (s[i] == '#') {
			cout << '#';
		} else if (i == 0 || s[i - 1] == '#') {
			cout << 'o';
		} else {
			cout << '.';
		}
	}
	cout << endl;
	return 0;
}

posted:
last update: