专栏文章
题解:AT_arc113_e [ARC113E] Rvom and Rsrev
AT_arc113_e题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minqzobd
- 此快照首次捕获于
- 2025/12/02 06:55 3 个月前
- 此快照最后确认于
- 2025/12/02 06:55 3 个月前
看看样例,发现要对 、 的位置和数量分讨。
用 表示一段极长连续 , 表示一段极长连续 。答案只有三种情况:
- 或者 ;
- ;
- ;
- 。
我们要做的操作是尽量把 向前挪动,直到挪不了或者挪了不优的时候才留下 。
考虑最终答案对应的 的情况。
或
如果 里字母相同,什么都不做是最优的,否则会使字母数量变少。
不满足前面的所有条件。如果 且 有偶数个,我们要让 尽量向前挪动,直接把 删完即可。
不满足前面的所有条件。如果 ,且 为奇数时, 删不完,让 尽量向前挪动,那就剩下一个 最优。
此时的答案,当 确定时,我们应该让 可能长。
结尾是
不满足前面的所有条件。如果 结尾是 ,那么我们操作会是一直删 使 向前挪,并且末尾留下 尽量长。
先除去最后一段 ,设剩下的 的段有 个, 的段有 个。
我们每次操作,取最后一段 和第一段 的第一个位置,把第一段 拼到最后一段,把最后一段 转到前面。
这样会删掉 个 ,使得 中除了最后一段 只剩下 的段。
这样会删掉 个 ,使得 中除了最后一段 只剩下 的段。
我们为了使剩下末尾的 尽量长,就让 的两两删,不够了再从末尾的 里拿一个出来,这样操作会减掉 个 。
最后 中的 个数不变且被挪到了最前面, 减少了 个。
结尾是
不满足前面的所有条件。如果 结尾是 且有奇数个 ,假如我们直接先删 使 ,那么我们再删两个 把 挪到后面更优。
也就是说我们为了把后面的 挪到前面去,一定会删掉两个 。那我们可以先删 ,把一段 挪到末尾,然后将 向前挪并让末尾的 尽可能长,这对于先删 来说一定不劣。
我们选择操作一段 的前后两个 ,把这段 转到最后,然后就和上面 结尾是 的情况相同了。
注意如果 开头不为 ,那么我们无法让第一段 转到最后。
如果 ,且 ,那么我们不能挪动中间的 。因为如果操作完之后更优,应该满足 。
此时我们把前面的 两两删掉,留下最后的一个 即可。
对应答案 。
此时我们把前面的 两两删掉,留下最后的一个 即可。
对应答案 。
代码
CPPinline int w(int w1,int w2){
return 2*w2+w1+(w1&1);
}
inline void solve(){
int len = strlen(s+1);
for(int i=1;i<=len;++i){
cnta[i] = cnta[i-1]+(s[i]=='a');
cntb[i] = cntb[i-1]+(s[i]=='b');
}
if(!cnta[len] || !cntb[len]){
for(int i=1;i<=len;++i) putchar(s[i]);
return ;
}
if(s[len]=='b' && !(cnta[len]&1)){
for(int i=1;i<=cntb[len];++i) putchar('b');
return ;
}
if(cnta[len-cntb[len]]==cnta[len] && (cnta[len]&1)){
putchar('a');
for(int i=1;i<=cntb[len];++i) putchar('b');
return ;
}
if(s[len]=='b'){
int lasa = len;
for(int i=len;i;--i){
if(s[i]^'b'){
lasa = i;
break;
}
}
if(len-lasa<=2){
for(int i=1;i<=cntb[lasa];++i) putchar('b');
putchar('a');
for(int i=cntb[lasa]+1;i<=cntb[len];++i) putchar('b');
return ;
}
}
int las = 0,w1 = 0,w2 = 0;
for(int i=1;i<=len;++i){
if(s[i]=='b'){
if(i-1-(las+1)+1==1) ++w1;
else if(i-1-(las+1)+1>1) ++w2;
las = i;
}
}
if(s[len]=='a'){
for(int i=1;i<=cntb[len];++i) putchar('b');
for(int i=1;i<=cnta[len]-w(w1,w2);++i) putchar('a');
return ;
}
int tw = 0;
if(s[1]=='b')tw = Min(w(w1-1,w2),w(w1,w2-1));
else{
int f = -1;
for(int i=1;i<=len;++i){
if(s[i]=='b'){
f = (i>3);
break;
}
}
if(f){
if(w2==1) tw = w(w1-1,w2);
else tw = Min(w(w1-1,w2),w(w1,w2-1));
}
else{
if(w1==1) tw = w(w1,w2-1);
else tw = Min(w(w1-1,w2),w(w1,w2-1));
}
}
for(int i=1;i<=cntb[len]-2;++i) putchar('b');
for(int i=1;i<=cnta[len]-tw;++i) putchar('a');
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...