首页 > 其他分享 >双指针习题:Binary Deque

双指针习题:Binary Deque

时间:2025-01-14 11:56:48浏览次数:1  
标签:case Binary Deque sum leq operations test 习题 array

14.Binary Deque

题面翻译

Binary Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

有多组数据。

每组数据给出 \(n\) 个数,每个数为 \(0\) 或 \(1\) 。你可以选择从两边删数,求至少删几个数才可以使剩下的数总和为 \(s\) 。

如果不能达到 \(s\) ,则输出 \(-1\) 。

题目描述

Slavic has an array of length $ n $ consisting only of zeroes and ones. In one operation, he removes either the first or the last element of the array.

What is the minimum number of operations Slavic has to perform such that the total sum of the array is equal to $ s $ after performing all the operations? In case the sum $ s $ can't be obtained after any amount of operations, you should output -1.

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases.

The first line of each test case contains two integers $ n $ and $ s $ ( $ 1 \leq n, s \leq 2 \cdot 10^5 $ ) — the length of the array and the needed sum of elements.

The second line of each test case contains $ n $ integers $ a_i $ ( $ 0 \leq a_i \leq 1 $ ) — the elements of the array.

It is guaranteed that the sum of $ n $ over all test cases doesn't exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output a single integer — the minimum amount of operations required to have the total sum of the array equal to $ s $ , or -1 if obtaining an array with sum $ s $ isn't possible.

样例 #1

样例输入 #1

7
3 1
1 0 0
3 1
1 1 0
9 3
0 1 0 1 1 1 0 0 1
6 4
1 1 1 1 1 1
5 1
0 0 1 1 0
16 2
1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1
6 3
1 0 1 0 0 0

样例输出 #1

0
1
3
2
2
7
-1

提示

In the first test case, the sum of the whole array is $ 1 $ from the beginning, so we don't have to make any operations.

In the second test case, the sum of the array is $ 2 $ and we want it to be equal to $ 1 $ , so we should remove the first element. The array turns into $ [1, 0] $ , which has a sum equal to $ 1 $ .

In the third test case, the sum of the array is $ 5 $ and we need it to be $ 3 $ . We can obtain such a sum by removing the first two elements and the last element, doing a total of three operations. The array turns into $ [0, 1, 1, 1, 0, 0] $ , which has a sum equal to $ 3 $ .

思路:

本题可以使用双指针来动态获取最优解,我们可以先计算出所有元素之和sum,若sum小于s,则不可能达到目标,输出-1并接着处理下一个样例,若s==sum,则正好操作次数为0,可以输出0并直接返回。否则,我们使用双指针的思路,此处为快慢指针,我们维护一个动态区间。

  1. 若这个动态区间内的元素之和sum=s,则我们此时更新答案,并让快指针向右走
  2. 若这个动态区间内的元素之和 sum<s,则我们需要扩大区间范围,此时让快指针r接着向右走
  3. 若这个动态区间内的元素之和sum>s,则我们需要缩小区间范围,找到最优的答案,此时应该是让慢指针向右走,逐步缩小这个区间的大小。
    需要注意的是,sum<s和sum>s时,对l和r做自增运算的顺序不同,sum>s时,我们需要加上r右边的这个元素,所以应该是让r先自增,再让sum+=a[r]
    而sum<s时,我们要减去l这个位置的元素,则我们是先sum-=a[l],再让l++。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,s;
int a[N];
void solve(){
    int n,s;
    cin>>n>>s;
    int sum=0;
    //先计算所有的元素之和,若所有元素之和还小于s,则不可能达到目标,若刚好等于s,则操作次数为0次。
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    if(sum<s){
        cout<<-1<<"\n";
        return;
    }
    if(sum==s){
        cout<<0<<'\n';
        return;
    }
    sum=a[1];
    int l=1,r=1,ans=1e10;
    while(r<=n&&l<=r){
        //若当前区间的和等于s,则此时更新答案,并且让快指针接着往后走
        if(sum==s){
            //当前所需要删除的数的个数为:总个数n-区间的长度。
            ans=min(ans,n-(r-l+1));
            r++;
            sum+=a[r];
        }
        //若当前区间的和小于s,则让快指针向右走,扩大区间的范围。
        if(sum<s){
            r++;
            sum+=a[r];
        }
        //若当前区间的和大于s,则让慢指针向右走,减少区间的长度,看看能不能达到最优的答案,
        //注意这里是先减去a[l],再让l++,与上面不同。
        if(sum>s){
            sum-=a[l];
            l++;
        }
    }
    cout<<ans<<'\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;cin>>t;
    while(t--) solve();
    return 0;
}

标签:case,Binary,Deque,sum,leq,operations,test,习题,array
From: https://www.cnblogs.com/Tomorrowland/p/18670484

相关文章

  • C语言初阶习题(2分支语句和循环语句-for)【10】杨辉三角
    1.题目描述——在屏幕上打印杨辉三角。2.思路第一步先尝试打印下三角第二步,分析他们之间的关系3.代码实现#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>intmain(){ intn=0; scanf("%d",&n); intarr[100][100]={0}; inti=0; in......
  • C语言初阶习题【27】猜名次
    1.题目描述5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。2.思路3.代码实现#include<stdio.h>in......
  • Hive SQL必刷练习题:复购率问题
    是说这个数据表中,找到最后一天,也就是今天的日期,max(date)over()Stoday【借助开窗函数】截至最后一天位置,也就是“今天“,表中的最新的一天去看90天内“某商品复购率=近90天内购买它至少两次的人数÷购买它的总人数”首先分析两个度量值,统计粒度是不一样的近90天内......
  • 背包九讲练习题
    01背包有N种物品和一个容量为V的背包,每种物品只有1个,第i种物品的体积为v[i],价值为w[i]。问将哪些物品装入背包,可使总体积不超过背包容量,且总价值最大,输出最大值。0<N,V<=1000;0<v[i],w[i]<=1000#include<bits/stdc++.h>intmain(){intN,V;std::cin>>N>>V;......
  • 2025华为OD机试已正式切换E卷,E卷新题正在火热更新中,支持在线OJ练习题目,三种语言解答,每
    文章目录......
  • 终于等到你!“西瓜书”《机器学习》官方配套习题集重磅出版
    欢迎关注博主Mindtechnist或加入【智能科技社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关注公粽号《机器和智能》回复关键词“python项目实战......
  • 《软件测试技术》习题参考答案2
    ......
  • ftp.retrbinary() 帮助 python
    ftp.retrbinary()帮助python`ftp.retrbinary()`函数用于从FTP服务器下载二进制文件(如图片、音频等)。这个函数需要两个参数:一个是文件名,另一个是回调函数,用于处理每次接收到的数据块。下面是一个详细步骤的代码示例:```pythonimportftplib#创建一个FTP连接ftp=ftplib......
  • 我在广州学 Mysql 系列——与索引相关的练习题
    ℹ️大家好,我是练小杰,今天星期二啦,还有三天就是星期五了,为了美好生活奋斗吧朋友们!本文将学习MYSQL中数据表内容的索引相关练习题目~~复习:......
  • [数据结构学习笔记8] 二叉查找树(Binary Search Trees)
    二叉查找树,它是一类特殊的二叉树,除了基本的二叉树规则外,还要满足:1.左边的子节点要小于父节点值2.右边的子节点要大于父节点值 图示:添加节点:        42       |   |      24  99      |    | ......