给定一个01串,找到多少个至少包含a个0,b个1的字串(尺取法,思维呀

先考虑最暴力的情况,左边界确定,只要找到一个右边界,那么这个右边界右边的所有选择都是合法的。

每次确定一个左边界,独立找出去,一定TLE。

但我们发现当《当每次枚举的左边界向右移动的时候,和前一次右边界相比,右边界显然不会向左移动》,所以用双指针法

nt f[1000010],g[1000010],n,a,b;
void solve()
{
    cin>>n>>a>>b;

    string s; cin>>s;
    s=" "+s;        //字符串下标就可以从1开始啦
    for(int i=1;i<=n;i++)
    {
        f[i]=f[i-1],g[i]=g[i-1];
        if(s[i]=='0') f[i]++;//记录枚举到第i个字符时,0的个数
        else g[i]++;//记录枚举到第i个字符时,1的个数
       //f[] g[]是排好升序的 ?
    }

    int ans=0;

    for(int i=1;i<=n;i++)
    {//每次i是《固定》的左边界

        int l = i,r = n;//双指针法l,r

        while(l<r)//双指针移动
        {
            int mid=(l+r)>>1;//二分法
            if( f[mid]-f[i-1] >=a && g[mid]-g[i-1]>=b) //r向前走,不断缩小左右指针的距离
               
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值