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];
    }
}
posted @ 2025-04-15 19:31  Marinaco  阅读(21)  评论(0)    收藏  举报
//雪花飘落效果