「TAOI-2」Break Through the Barrier
题面
P9574
题意
给定一个字符串
求操作若干次(可以零次)后,
证明直接模拟即可。这告诉我们 若干
看到
举个例子:
两端都是
证明完毕。
所以一种朴素的做法就出现了。
记录原串中长度
赛时本以为只能过 没想到直接过了。
为什么能过呢?考虑证明复杂度。
空间复杂度显然
首先,当
当 但是良心出题人没有卡,当然也可以先判长度为
当
代码
常数巨大。
#include<bits/stdc++.h>
using namespace std;
int n,T;
int s[100003];
struct node{
int l,r;
}t[100003]; int cnt;
signed main(){
cin>>T;
while(T--){
int flag=1; cnt=0;
cin>>n;
for(int i=1;i<=n;i++){
char c;
cin>>c;
s[i]=c=='T';
}
for(int i=1;i<=n;i++){ // 判断是否存在 BTTB 串
if(!s[i]&&s[i+1]&&s[i+2]&&!s[i+3]){
flag=0;
break;
}
}
int mx=0,lastmx=0,len=0;
for(int i=1;i<=n;i++){
if(s[i]) len++;
else mx=max(mx,len),len=0;
}
mx=max(mx,len); len=0; lastmx=mx; // 找最长的 T 串
if(flag){
cout<<mx;
}else{
for(int i=1;i<=n;i++){
if(s[i]) len++;
else{
if(len>=mx-1) t[++cnt]={i-len,i-1};
len=0;
}
}
if(len>=mx-1) t[++cnt]={n-len+1,n};
len=0; // 找所有长度大于等于 mx-1 的 T 串
for(int i=1;i<=cnt;i++){
int l=t[i].l-1,r=t[i].r+1,add=0;
while(l>1&&!s[l]&&s[l-1]) l-=2; // 遍历找左边的 TB
if(l>1&&s[l]&&!s[l-1]) add++; // 找左边是否存在 BT
while(r<n&&!s[r]&&s[r+1]) r+=2; // 遍历右边的 BT
if(r<n&&s[r]&&!s[r+1]) add++; // 找右边是否存在 TB
mx=max(mx,t[i].r-t[i].l+1+add); // 更新答案
if(lastmx==mx-2) break;
}
cout<<mx;
}
cout<<"\n";
}
return 0;
}
Rising sun traxx 里面的欸。