[eJOI2018] AB Strings 题解
考虑到一个简单的性质:如果一个串中有连续的两个相同的字符,那么可以将它们视为一个字符;于是最后两个串都形如
接着分类讨论,对于两个字符串首字母相同的情况(不妨设为
对于边界情况:其中一个字符串长度为
参考代码(GNU C++17):
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
vector<pii> q[2],r;
inline void add(int p,pii x){
if(!q[p].empty()&&q[p].back().first==x.first)
q[p].back().second+=x.second;
else q[p].emplace_back(x);
}
inline void op(int x){
pii a=q[0].back(); q[0].pop_back();
int c=0;
for(int i=x;i;i--){
pii y=q[1][q[1].size()-i];
add(0,y),c+=y.second;
}
r.emplace_back(a.second,c);
while(x--)q[1].pop_back();
add(1,a);
}
int main(){
ios::sync_with_stdio(false);
string s,t; bool f=false; cin>>s>>t;
for(int i=s.length()-1;~i;i--)
add(0,make_pair(s[i]&1,1));
for(int i=t.length()-1;~i;i--)
add(1,make_pair(t[i]&1,1));
if(q[0].size()>q[1].size())
swap(q[0],q[1]),f=true;
if(q[0].back().first==q[1].back().first){
if((q[1].size()-q[0].size()&3)==3)
op(q[1].size()-q[0].size()+1>>1);
add(0,make_pair(!q[0].back().first,0));
op(q[1].size()-q[0].size()+1>>2<<1|1);
}
else if(q[1].size()-q[0].size()>2)
op(q[1].size()-q[0].size()+1>>2<<1|1);
while(q[0].size()>1||q[1].size()>1)op(1);
if(f)for(auto &[x,y]:r)swap(x,y);
cout<<r.size()<<endl;
for(auto [x,y]:r)cout<<x<<' '<<y<<'\n';
return 0;
}