公式
E - ABC|AB|A 解説 by evima
In this editorial, we take the approach of examining \(S\) from the back.
The following algorithm solves this problem.
- Prepare an empty stack, and initialize the answer as \(r=|S|\).
- For each character \(c\) of \(S\), in order from the back, repeat the following.
- If \(c=\)
C:- Push \(0\) onto the top of the stack.
- If \(c=\)
B:- If \(0\) is on top of the stack, pop it and push \(3\) instead.
- Otherwise, push \(2\) onto the top of the stack.
- If \(c=\)
A:- If a positive integer is on top of the stack, pop it and subtract it from \(r\).
- Otherwise, subtract \(1\) from \(r\).
- If \(c=\)
The correctness can be explained as follows.
- The integers pushed onto the stack in this solution correspond to the following states.
- \(0\) …
C - \(2\) …
B - \(3\) …
BC
- \(0\) …
- If a
Cappears, we cannot touch the characters after it unless we delete thatC. - If a
Bappears- If it is immediately followed by
C, we can delete thatCat the same time as deleting theB. - If it is immediately followed by another
B, we cannot touch the characters after it unless we delete theBthat appeared.
- If it is immediately followed by
- If an
Aappears, there is no reason to keep thatA, and it should be deleted immediately.- If it is followed by
C, we cannot delete them together, but if it is followed byBorBC, we can delete them together.
- If it is followed by
The time complexity of this solution is \(O(|S|)\).
Sample Implementation (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--){
string s;
cin >> s;
reverse(s.begin(),s.end());
stack<int> st;
int res=s.size();
for(auto &nx : s){
if(nx=='C'){
st.push(0);
}
else if(nx=='B'){
if(st.size()>0 && st.top()==0){st.pop(); st.push(3);}
else{st.push(2);}
}
else{
if(st.size()>0 && st.top()>0){res-=st.top(); st.pop();}
else{res--;}
}
}
cout << res << "\n";
}
return 0;
}
投稿日時:
最終更新: