kou6839の日記

c++ 競プロ(特にcsacademy) linuxについて書きます。普段は自動車屋さんでナビ開発してます。転職先を探しています!!。

CSACademy K Consequal

csacademy.com

<問題>
長さNの文字列が与えられます。
長さKの連続する部分文字列があるとき、それらを取り除きます。
以降、取り除かれた文字を繰り返し、操作ができなくなるまで取り除きます。
残った文字を出力してください。

<解説>
stackを使います。
stackに(文字、連続する回数)を詰めていき、
追加する文字が1つ前の元の同じかどうかで分岐していきます。
対応する括弧()系の文字と同様に、繰り返し取り除く系では典型??

<コード>

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);


	int n, k;
	cin >> n >> k;
	string s;
	cin >> s;
	if (k == 1) {
		P("");
		return 0;
	}
	
	stack<pair<char, int>> st;

	st.push(make_pair(s[0], 1));

	for (int i = 1; i < n; i++) {
		if (st.top().first == s[i] && st.top().second == k - 1) {
			st.pop();
		}
		else if (st.top().first == s[i]) {
			st.top().second++;
		}
		else {
			st.push(make_pair(s[i],1));
		}
	}

	string ans = "";
	while (!st.empty()) {
		rep(i, st.top().second)ans += st.top().first;
		st.pop();
	}
	reverse(ALL(ans));
	P(ans);
	return 0;
}

<感想>
上記のコードは出力時に反転させていますが、
公式解説のコードはdeckを使っていて、その処理を省いています。
そういう綺麗なコードを使いたい。