[codeforces] Binary Deque

本文介绍了如何通过C++编程解决关于BinaryDeque的问题,利用滑动窗口和双指针策略,计算在给定条件下最少操作次数以达到目标数s,或判断是否可能实现。
摘要由CSDN通过智能技术生成

[codeforces] Binary Deque

在这里插入图片描述
在这里插入图片描述

题意:

二进制双端队列,数组里的数是0,1,每一次删除可以选择最后一个或第一个,问最少操作几次后得到要求的数s,如果怎么操作都没法得到s,输出-1。

可以这样想,我操作总次数可以看作是对左端和右端操作的次数的和,这个就相当于一个滑动窗口

以第三个例子为例
在这里插入图片描述
像这种滑动窗口要通过维护一段子列来解决,我们用双指针法来解决。(这里的指针更像是一种标记点,符合题意标记点移动)

sum为和,l,r为左右指针,初始值为1

sum=s时,更新答案,并且我们r指针向右移动

sum<s时,r指针向右移动,使sum尽可能增大

sum>s时,l指针向右移动,使sum尽可能减小

直到l,r中某个越界为止
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int t;
int n, s;
const int N = 2e5 + 5;
int a[N];
int main()
{

    cin >> t;
    for (int i = 0; i < t; i++)
    {
        cin >> n >> s;
        int sum = 0;int ans = 0x3fffffff;//0x3fffffff是代表无穷大的意思,因为取最小值,所以初始数大一点,而且注意不能搞成全局变量,因为有很多测试数据,要保证每一次的ans初始为无穷大
        for (int j = 1; j <= n; j++)
        {
            cin >> a[j];
            sum += a[j];
        }
        if (sum == s) { cout << 0 << endl; }//总和等于s,肯定不用操作,因为有操作就不是最小了
        else if (sum < s) { cout << -1 << endl; }//总和小于s,直接输出-1得了,因为本题的操作后的数的总和本来就是会变小的
        else
        {
            sum = a[1];
            int l = 1, r = 1;
            while (l <= n && r <= n)
            {
                if (sum == s)
                {
                    ans = min(ans, n - r + l - 1);
                    r++;
                    sum += a[r];
                }
                else if (sum < s)
                {
                    r++;
                    sum += a[r];//这里是移动右指针,是要把右边的数加上,只能移动后才能加
                }
                else
                {
                    sum -= a[l];//这里的逻辑是左指针向右移动,它要使sum变小,应该要把左边的数减掉,所以先减再移动指针
                    l++;
                }
            }
            cout << ans << endl;
        }
        memset(a, 0, sizeof(a));//初始化数组为0,不然有一部分数还残余在里面,影响后面计算
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值