2025年第九届河北省CCPC大学生程序设计竞赛J. Generate 01 String题解

问题:初始有个标识符S,可以进行两种操作: 1 将第pos 个标识符S变成0S1S。 2 将第pos 个标识符S变成1S0S。 最终所有的标识符消失,只保留字符串中的01字符。 现在给出01串T,问能否生成,如果能生成输出操作次数与步骤,如果不能,输出-1。 1 ≤|T| ≤ 106。

样例:输入:0011

           输出:2

                      1   1

                      1   1

样例解释:最初为S,第一次操作1 1,得到0S1S.第二次操作1 1,得到00S1S1S,最后操作符消失,得到0011.

 解答:首先不难发现,每次将标识符变为0S1S或者1S0S时,0,1都是成对增加,因此最终生成的01串必然满足字符0的数量等于字符1的数量,同时操作次数必然为T/2,故而可以将num0与num1是否相等视作一种验证能否生成的方法,可以在输入01串之后判断一下,如果不相等直接输出-1并返回。

           之后观察发现,S的位置相对于单次操作后总是出现在相对位置后的第2个,第4个位置,故而可以很轻易的通过S调整0,1出现的位置,因此可以大胆假设出,只要0,1的个数相等,便可以轻易的通过S生成相应的0,1串。那么不妨把处理整个大的01串的问题转化为大01串中连续且0,1个数相等的小01串问题,即“划分子问题”。

           于是乎对于子串,就有以下两种情况,01(10)连续,与01(10)不连续(出现00,11),于是可以想到利用栈容器(stack)进行捕捉和模拟是否出现连续,当遇到与栈顶相同的数时,将其入栈,相当于对新的标识符进行操作,当遇到不同的符号时,将其出栈,模拟标识符消失的过程,并更新下次操作S的位置,这样就能通过栈来模拟整个操作过程,确定每次针对的标识符位置和类型。

   AC代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long
string str;
stack <char>sta;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>str;
    int num1=count(str.begin(),str.end(),'1');
    int num0=count(str.begin(),str.end(),'0');
    //判断0,1数是否相等
    if(num1!=num0)
    {
        cout<<-1<<endl;
        return 0;
    }
    //输出操作数,即01串长度的一半
    cout<<num1<<endl;
    int i=0;//遍历下标
    int pos=1;//所要更改的S的位置
    while(i<str.size())
    {
        char c=str[i];
        if(sta.empty()||sta.top()==c)
        {
            //相等入栈,操作新的标识符
            sta.push(c);
            cout<<pos<<" "<<c-'0'+1<<endl;
        }
        else
        {
            //不相等出栈,改变要操作的S的位置
            sta.pop();
            pos++;
        }
        i++;
    }
    return 0;
}

  由于本蒟蒻实力有限,无法补完所有的题,故只能选做且一个一个发题解,望谅解。

  最后嘞------求点赞关注!!   !           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值