1 条题解

  • 0
    @ 2026-4-2 15:35:42

    题解

    题意简述

    给定一个由 0011 组成的字符串 ss。每次操作可以选出一个非空子序列 tt,要求 tt 中任意相邻字符不同(即 tt 是交替的 0011 序列),然后将 tt 中的每个字符翻转(00111100)。求将整个字符串变为全 00 所需的最少操作次数。

    解题思路

    结论:最少操作次数等于字符串中 11 的个数。

    证明

    1. 下界
      考虑一次操作中翻转的 11 的个数为 aa,翻转的 00 的个数为 bb。操作后,11 的数量的变化量为 bab - a(因为每个 11 变成 00 会减少 1111,每个 00 变成 11 会增加 1111),即净减少 aba - b11
      由于选出的子序列 tt 是交替的,若 tt11 开头,则序列模式为 1,0,1,0,1,0,1,0,\dots,设长度为 kk,则 a=k/2a = \lceil k/2 \rceilb=k/2b = \lfloor k/2 \rfloor,故 ab=0a - b = 0kk 为偶数)或 11kk 为奇数)。若 tt00 开头,则 a=k/2a = \lfloor k/2 \rfloorb=k/2b = \lceil k/2 \rceilab=0a - b = 01-1
      因此,一次操作最多使 11 的数量减少 11。初始有 count1\text{count}_111,最终为 0011,故至少需要 count1\text{count}_1 次操作。

    2. 上界
      我们可以每次只选择一个单独的 11 作为子序列(单个字符显然满足相邻字符不同的条件),将其翻转为 00。这样每次操作恰好减少一个 11,因此 count1\text{count}_1 次操作即可完成。
      所以最少操作次数不会超过 count1\text{count}_1

    综上,最少操作次数就等于字符串中 11 的个数。

    算法实现

    直接统计字符串中字符 11 的个数并输出即可。时间复杂度 O(s)O(|s|),空间复杂度 O(1)O(1)

    参考代码(标程)

    #include<bits/stdc++.h>
    using namespace std;
    string s;
    int main(){
        ios::sync_with_stdio(false),cin.tie(0);
        int T,n,i,ans;
        for(cin>>T;T>0;T--){
            cin>>s; n=s.size();
            ans=0;
            for(i=0;i<n;i++) ans+=s[i]-'0';
            cout<<ans<<'\n';
        }
        return 0;
    }
    
    • 1

    信息

    ID
    6230
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者