A题

暴力就可以

void solve(){
    cin>>s;
    for(int i=1;i<s.size();i++){
        if(s[i]!=s[i-1]) sum++;
    }
    cout<<sum;
}

B题

数学题,找到每一段符合条件的子串,然后这一条符合条件的子串有(1+len(s)-1)/2符合条件,注意的就是处理最后一段,就好了。

void solve(){
    cin>>s;
    ll j=0;
    ll i=1;
    for(i=1;i<s.size();i++){
        if(s[i]==s[i-1]&&i-j+1>=2){
            sum+=(1+i-j-1)*(i-j-1)/2;
            j=i;
            
        }
    }
    if(i-j+1>=2) sum+=(i-j)*(i-j-1)/2;
    cout<<sum;
}

C题

如果k是奇数的话就可以构造成1111101010000000,旁边是多余的01,中间是k对不相同相邻的字符串。如果是偶数,就构造成1111101010000001,与奇数不同的就是把后面的多余的01,放到n-1的位置(把这一段k看成整体),然后就是构造不出的

void solve(){
    ll a,b,k;
    cin>>a>>b>>k;
    string s="";
    if((a!=b&&min(a,b)*2<k)||(a==b&&a*2-1<k)||(k==0&&a+b!=max(a,b))){
        cout<<"-1\n";
        return;
    }
    int sa=0,sb=1;
    if(a>b) swap(a,b),swap(sa,sb);
    if(k%2==1){
        for(int i=0;i<=b-(k+1)/2;i++){
            s+=('0'+sb);
        }
        for(int i=0;i<k;i++){
            if(i%2) s+='0'+sb;
            else s+='0'+sa,a--;
        }
        while(a--) s+='0'+sa;
    }
    else{
        for(int i=0;i<=b-k/2-1;i++){
            s+='0'+sb;
        }
        b-=b-(k+1)/2;
        for(int i=0;i<k-1;i++){
            if(i%2) s+='0'+sb,b--;
            else s+='0'+sa,a--;
        }
        while(a--) s+='0'+sa;
        if(b) s+='0'+sb;
    }
    cout<<s<<'\n';
}

D题

先预处理出当前位置的下一个相同的位置在哪里,下一个不相同的位置在哪里,然后就很简单的dp一下就可以了。

//a[i]当前位置下一个相同的,b[i]当前位置下一个不相同的
void solve(){
    cin>>n>>x>>y;
    cin>>s;
    s=' '+s;
    int t0=-1,t1=-1;
    for(int i=n;i>=1;i--){
        if(s[i]=='0'){
            a[i]=t0;
            b[i]=t1;
            t0=i;
        }
        else{
            a[i]=t1;
            b[i]=t0;
            t1=i;
        }
        dp[i]=1e18;
    }
    dp[0]=dp[1]=0;
    for(int i=1;i<=n;i++){
        if(a[i]!=-1) dp[a[i]]=min(dp[i]+x,dp[a[i]]);
        if(b[i]!=-1) dp[b[i]]=min(dp[b[i]],dp[i]+y);
    }
    cout<<dp[n];
}