D-logical filling
题目链接:https://atcoder.jp/contests/abc401/tasks/abc401_d
题意:
给定一个字符串,其中‘?’字符可以替换成'.'或'o'。我们想要这个字符出现k个o,并且每个o都不相邻
每个问号都可以替换的情况下,既可以替换成.也可以替换成o的问号依旧是问号
输出构造的字符串
思路:
易知原串每个o旁边的问号都是.,先行替换
对于每一个连续的?序列,求出最大能装多少个o,记为cnt(显然偶数能装区间长度len/2个,奇数最多装(len+1)/2个)
求出我们需要获得多少个o
如果cnt=need,说明要最大化o
cnt>need,说明每个问号都有两种选择的情况
特判,当need=0时,问号必须都是.
void solve(){
int n,k;cin>>n>>k;
string s;cin>>s;s=" "+s;
int cnt=0;
rep(i,1,n){
if(s[i]=='o'){
if(i-1>=1&&s[i-1]=='?'){
s[i-1]='.';
}
if(i+1<=n&&s[i+1]=='?'){
s[i+1]='.';
}
cnt++;
}
}
int dif=k-cnt;
if(dif==0){
rep(i,1,n){
if(s[i]=='?')cout<<'.';else cout<<s[i];
}return;
}
int sum=0;
vector<pii>interval;
rep(i,1,n){
if(s[i]=='?'){
int l,r;
l=r=i;
while(i+1<=n&&s[i+1]=='?'){
i++;
}
r=i;
int len=r-l+1;
sum+=(len+1)/2;
interval.pb({l,r});
}
}
if(sum==dif){
for(auto x:interval){
int l=x.fi,r=x.se;
if((r-l+1)%2==1){
for(int i=l;i<=r;i+=2){
s[i]='o';
}
for(int i=l+1;i<=r-1;i+=2){
s[i]='.';
}
}
}
}
rep(i,1,n){
cout<<s[i];
}
}

浙公网安备 33010602011771号