[蓝桥杯] 二分与前缀和习题练习

news2024/11/26 23:46:34

 

文章目录

一、二分查找习题练习

1、1 数的范围

1、1、1 题目描述

1、1、2 题解关键思路与解答

1、2 机器人跳跃问题

1、2、1 题目描述

1、2、2 题解关键思路与解答

1、3 四平方和

1、3、1 题目描述

1、3、2 题解关键思路与解答

二、前缀和习题练习

2、1 前缀和

2、1、1 题目描述

2、1、2 题解关键思路与解答

2、2 子矩阵的和

2、2、1 题目描述

2、2、2 题解关键思路与解答

三、总结


标题:蓝桥杯——二分与前缀和习题练习

作者:@Ggggggtm

寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景

  又来更新了。二分与前缀和是蓝桥杯比较常考的内容,所以我们要多加练习这方面的习题。二分与前缀和的难度相对来说不算大,我们应该掌握其关键要点。

一、二分查找习题练习

1、1 数的范围

1、1、1 题目描述

题目来源:模板题,AcWing

题目难度:简单

题目描述:

  给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

  对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

  如果数组中不存在该元素,则返回 -1

输入格式:

  第一行包含整数 n 和 q,表示数组长度和询问个数。

  第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。

  接下来 q 行,每行包含一个整数 k,表示一个询问元素。

输出格式:

  共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

  如果数组中不存在该元素,则返回 -1

数据范围:

1≤n≤100000
1≤q≤10000
1≤k≤10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

1、1、2 题解关键思路与解答

  简单总结上述题目,就是让我们找出要求相同的数的左右区间。也就是我们需要找出要求的数的左边界与右边界。因为题目中描述的是有序的,所以我们在这里用二分就可以很容易找到题目所要求的左右边界。我们直接看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int n,m;
const int N=100010;
int arr[N];

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
        scanf("%d",&arr[i]);
    while(m--)
    {
        int k;
        scanf("%d",&k);
        int l=0,r=n-1;
        while(l<r)
        {
            int mid=l+r>>1;
            if(arr[mid]>=k)
                r=mid;
            else
                l=mid+1;
        }
        if(arr[l]==k)
        {
            cout<<l<<' ';
            r=n-1;
            while(l<r)
            {
                int mid=l+r+1>>1;
                if(arr[mid]<=k)
                    l=mid;
                else
                    r=mid-1;
            }
            cout<<l<<endl;
        }
        else
        {
            cout<<"-1 -1"<<endl;
        }
    }
    return 0;
}

1、2 机器人跳跃问题

1、2、1 题目描述

题目来源:今日头条2019笔试题

题目难度:简单

题目描述:

  机器人正在玩一个古老的基于 DOS 的游戏。

  游戏中有 N+1 座建筑——从 0 到 N 编号,从左到右排列。

  编号为 0 的建筑高度为 0 个单位,编号为 i 的建筑高度为 H(i)个单位。

  起初,机器人在编号为 0 的建筑处。

  每一步,它跳到下一个(右边)建筑。

  假设机器人在第 k 个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1个建筑。

  如果 H(k+1)>E,那么机器人就失去 H(k+1)−E的能量值,否则它将得到 E−H(k+1)的能量值。

  游戏目标是到达第 N 个建筑,在这个过程中能量值不能为负数个单位。

  现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?

输入格式:

  第一行输入整数 N。

  第二行是 N 个空格分隔的整数,H(1),H(2),…,H(N) 代表建筑物的高度。

输出格式:

  输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。

数据范围:

  1≤N,H(i)≤10e5

输入样例1:

5
3 4 3 2 4

输出样例1:

4

输入样例2:

3
4 4 4

输出样例2:

4

输入样例3:

3
1 6 4

输出样例3:

3

1、2、2 题解关键思路与解答

  这个题我们可以用二分加枚举来计算,时间复杂度为O(n*logn),最大数据为1e5,也是可以通过的。具体就是,我们可以二分能量,然后通过能量再去枚举看是否可以通过。这里需要注意的是要整形溢出的问题。

#include<iostream>
#include<cstdio>

using namespace std;

int n;
const int N=100010;
int a[N];

bool jump(int e)
{
    for (int i = 0; i < n; i ++ )
    {
        //e = e * 2 - a[i];
        
        //if (e < 0) return false;
        if(a[i]>e)
            e-=(a[i]-e);
        else
            e+=(e-a[i]);
        
        if (e >= 1e5)
            return true;
        
        if(e<0)
            return false;
    }
    return true;
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    int min=0,max=100010;
    while(min<max)
    {
        int mid=min+max>>1;
        if(jump(mid))
            max=mid;
        else
            min=mid+1;
    }
    cout<<min<<endl;
    return 0;
}

1、3 四平方和

1、3、1 题目描述

题目来源:第七届蓝桥杯省赛C++A/B组,第七届蓝桥杯省赛JAVAB/C组

题目难度:中等

题目描述:

  四平方和定理,又称为拉格朗日定理:

  每个正整数都可以表示为至多 4 个正整数的平方和。

  如果把 0 包括进去,就正好可以表示为 4 个数的平方和。

  比如:

  对于一个给定的正整数,可能存在多种平方和的表示法。

  要求你对 4 个数排序:

  0≤a≤b≤c≤d,并对所有的可能表示法按 a,b,c,d为联合主键升序排列,最后输出第一个表示法。

输入格式:

  输入一个正整数 N。

输出格式:

  输出4个非负整数,按从小到大排序,中间用空格分开。

数据范围

  0<N<5∗1e6。

输入样例:

5

输出样例:

0 0 1 2

1、3、2 题解关键思路与解答

  由于题目给出的数据范围较大,所以我们在这里不能用暴力四层for循环来求解。我们可以先求出c和d两数的平方和,再把这两个数的平方和存起来并且排序。再去求a和b的平方和,通过二分去找已经算好的c和d的平方和,看是否满足条件。那我们如何保证0≤a≤b≤c≤d呢?我们再求和的时候是从大到小的,一旦找到解就返回即可。我们结合代码一起理解一下:

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 2500010;

struct Sum
{
    int s, c, d;
    bool operator< (const Sum &t)const
    {
        if (s != t.s) return s < t.s;
        if (c != t.c) return c < t.c;
        return d < t.d;
    }
}sum[N];

int n, m;

int main()
{
    cin >> n;

    for (int c = 0; c * c <= n; c ++ )
        for (int d = c; c * c + d * d <= n; d ++ )
            sum[m ++ ] = {c * c + d * d, c, d};

    sort(sum, sum + m);

    for (int a = 0; a * a <= n; a ++ )
        for (int b = a; a * a + b * b <= n; b ++ )
        {
            int t = n - a * a - b * b;
            int l = 0, r = m - 1;
            while (l < r)
            {
                int mid = l + r >> 1;
                if (sum[mid].s >= t) r = mid;
                else l = mid + 1;
            }
            if (sum[l].s == t)
            {
                printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
                return 0;
            }
        }

    return 0;
}

二、前缀和习题练习

2、1 前缀和

2、1、1 题目描述

题目来源:《算法竞赛进阶指南》

题目难度:简单

题目描述:

  输入一个长度为 n 的整数序列。

  接下来再输入 m 个询问,每个询问输入一对 l,r。

  对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。

输入格式:

  第一行包含两个整数 n 和 m。

  第二行包含 n 个整数,表示整数数列。

  接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。

输出格式:

  共 m 行,每行输出一个询问的结果。

数据范围:

  1≤l≤r≤n,
  1≤n,m≤100000,
  −1000≤数列中元素的值≤1000

输入样例:

5 3
2 1 3 6 4
1 2
1 3
2 4

输出样例:

3
6
10

2、1、2 题解关键思路与解答

   题目要求是求一段区间的和。数组的元素个数和询问次数的数据范围为0到1e5,暴力循环求解是不行。这里我们可以用到前缀和,使的求一段区间的和的值从O (N)的时间复杂度优化到了O(1)。我们直接看代码:

#include<iostream>
#include<cstdio>

using namespace std;

const int N=100010;

int n,m;

int a[N],s[N];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        s[i]=s[i-1]+a[i];
    }
        
    while(m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        
        printf("%d\n",s[r]-s[l-1]);
    }
    return 0;
}

2、2 子矩阵的和

2、2、1 题目描述

题目来源:《算法竞赛进阶指南》

题目难度:简单

题目描述:

  输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。

  对于每个询问输出子矩阵中所有数的和。

输入格式:

  第一行包含三个整数 n,m,q。

  接下来 n 行,每行包含 m 个整数,表示整数矩阵。

  接下来 q 行,每行包含四个整数 x1,y1,x2,y2,表示一组询问。

输出格式:

  共 q 行,每行输出一个询问的结果。

数据范围:

  1≤n,m≤1000,
  1≤q≤200000,
  1≤x1≤x2≤n,
  1≤y1≤y2≤m
  −1000≤矩阵内元素的值≤1000

输入样例:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出样例:

17
27
21

2、2、2 题解关键思路与解答

  该题的题录与前缀和思路大致相同,只不过这道题求的前缀和变成了二位的前缀和。建议画图,利用容斥原理,仔细分析一下即可。相对还是较为简单的。

#include<iostream>
#include<cstdio>

using namespace std;

const int N=1010;

int a[N][N],s[N][N];

int n,m,q;

int main()
{
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j];
        }
    
    while(q--)
    {
        int x1,x2,y1,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        
        printf("%d\n",s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]);
    }
    return 0;
}

三、总结

  通过上面的习题练习,我们发现二分和前缀和的思想很简单。同时,我们也要掌握上面的二分和前缀和的思路和方法。在很多情况下,会给我们带来很大的便利。

  二分和前缀和的练习就到这里,希望以上内容对你有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《操作系统》——第二章 进程与线程

目录 2.1.1进程的概念、组成、特征 2.1.2进程的状态与转换、进程的组织 2.1.3进程控制 2.1.4进程通信 2.1.5线程的概念 2.1.6线程的实现方式和多线程模型 2.2.1调度的概念、层次 2.2.2进程调度的时机、切换与过程、方式 2.2.4调度算法的评价指标 2.2.5调度算法(1) 2…

1249 亲戚(并查集)

1249. 亲戚 题目 提交记录 讨论 题解 视频讲解或许你并不知道&#xff0c;你的某个朋友是你的亲戚。 他可能是你的曾祖父的外公的女婿的外甥女的表姐的孙子。 如果能得到完整的家谱&#xff0c;判断两个人是否是亲戚应该是可行的&#xff0c;但如果两个人的最近公共祖…

数据库之高级查询

注意&#xff1a;第一个包含空&#xff0c;第二句不包含空注意&#xff1a;第二句是错的&#xff0c;聚合函数不能出现在where中。注意&#xff1a;相当于&#xff0c;按照分组属性&#xff0c;求出每个组的聚合函数值&#xff0c;所以肯定不能放单个属性有冲突with rollup是最…

MyBatis - 05 - 封装SqlSessionUtil工具类(用于获取SqlSession对象)并测试功能

文章目录1.新建SqlSessionUtils工具类2.编写静态方法3.项目结构及代码项目结构数据库和表pom.xmlParameterMapper接口&#xff1a;User类&#xff1a;ParameterMapper.xmljdbc.propertieslog4j.xml:mybatis-config.xml:ParameterMapperTest测试类&#xff1a;测试结果1.新建Sql…

leetcode打卡-回溯I

77. 组合 leetcode题目链接&#xff1a;https://leetcode.cn/problems/combinations/ leetcode AC记录&#xff1a; 代码如下&#xff1a; public List<List<Integer>> combine(int n, int k) {List<List<Integer>> res new ArrayList<>(16…

操作系统期末复习

操作系统概论 文章目录操作系统概论操作系统的目标&#xff1a;基本特征:主要功能发展操作系统的运行机制时钟管理中断机制&#xff1a;指令程序处理机状态原语&#xff1a;由若干指令组成的程序段&#xff0c;完成特定功能系统数据结构系统调用体系结构进程--资源分配和调度的…

[黑马程序员SSM框架教程] Spring-22 注解开发依赖注入

1.自动装配是基于暴力反射对私有属性进行装配的&#xff0c;所以不需要setter方法。打破了IOC提供对象&#xff0c;我提供入口的思想。现在不用提供入口也能实现。 2. Qualifier必须依赖注解Autowired&#xff0c;当自动装配的接口类型有多个实现类时使用&#xff0c; 3. Autow…

Linux基础命令-du查看文件的大小

文章目录 du 命令介绍 语法格式 基本参数 参考实例 1&#xff09;以人类可读形式显示指定的文件大小 2&#xff09;显示当前目录下所有文件大小 3&#xff09;只显示目录的大小 4&#xff09;显示根下哪个目录文件最大 5&#xff09;显示所有文件的大小 6&#xff0…

layui框架学习(11:徽章)

应用程序有新增内容、未读消息时&#xff0c;会在按钮或菜单中添加红点或带数字的点状或方状图形&#xff0c;用户看到就知道有新内容&#xff0c;如下图所示QQ邮箱的截图&#xff0c;会通过红色圆点或带NEW的方框提醒用户有新内容可以查看。   CSDN用户如果有新消息&#x…

产品经理有必要考个 PMP吗?(含PMP资料)

现在基本上做产品的都有一个PMP证件&#xff0c;从结果导向来说&#xff0c;不对口不会有这么大范围的人来考&#xff0c;但是需要因地制宜&#xff0c;在公司内部里&#xff0c;标准程序并不流畅&#xff0c;产品和项目并不规范&#xff0c;关系错综复杂。 而产品经理的职能又…

【Java学习】初识Java

JavaSEJava初识1. Java简介2.Java环境的安装与配置3. 开发第一个Java程序Java初识 学前疑问&#xff1a;&#xff08;带着疑问去学习&#xff0c;在学习中自行探索答案&#xff09; Java是什么&#xff1f;能做什么&#xff1f;发展前景如何&#xff1f;需要学习哪些内容&…

腾讯一面—Android 系统启动流程详解

正文AMS 是 Android 中最核心的服务之一&#xff0c;主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作&#xff0c;其职责与操作系统中的进程管理和调度模块相类似&#xff0c;它本身也是一个 Binder 的实现类&#xff0c;应用进程能通过 Binder 机制调用…

ESPRESSIF ESP32 开发环境搭建

1.下载Espressif-IDE并安装&#xff0c;安装的时候直接下一步就行&#xff0c;下载地址为 IDE下载地址 2.新建项目 1&#xff0c;首先磁盘新建文件夹&#xff0c;用来保存项目 2&#xff0c;File ->New ->乐鑫IDF项目-> 工程名字test->保存目录就是自己建立的哪个…

EasyRecovery16MAC苹果版本Photo最新版数据恢复软件

无论是在工作学习中&#xff0c;还是在生活中&#xff0c;Word、Excle等办公软件都是大家很常用的。我们在使用电脑的过程中&#xff0c;有时会因自己的误删或电脑故障&#xff0c;从而导致我们所写的文档丢失了。出现这样的大家不要着急&#xff0c;今天小编就给大家推荐一款可…

nacos 单机集群搭建及常用生产环境配置 | Spring Cloud 3

一、Nacos 概览 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮…

《程序员思维修炼》速读笔记

文章目录书籍信息概览绪论从新手到专家的历程认识大脑利用右脑调试大脑主动学习积累经验控制注意力超越专家图解书籍信息 书名&#xff1a;《程序员思维修炼&#xff08;修订版&#xff09;》 作者&#xff1a;[美] Andy Hunt 概览 绪论 再提“实用”关注情境所有人都关注这…

kafka使用入门案例与踩坑记录

每次用到kafka时都会出现各种奇怪的问题&#xff0c;综合实践&#xff0c;下面汇总下主要操作步骤&#xff1a; Docker镜像形式启动 zookeeper启动 docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeperkafka启动 docker run --name kafka01 -p 9092:909…

Apk转Aab(Android-App-Bundle)

这篇文章是参考Apk转Aab(Android-App-Bundle)_YoungBillsohu的博客-CSDN博客 基本照着这个大佬的步骤来就行&#xff0c;但是要注意的是apkTool最好是下新的&#xff0c;否则&#xff0c;会出现说一堆无语的错误&#xff0c;然后导致AAPT2关联资源的时候报错 类似这样的&#…

Java自定义生成二维码(兼容你所有的需求)

1、概述作为Java开发人员&#xff0c;说到生成二维码就会想到zxing开源二维码图像处理库&#xff0c;不可否认的是zxing确实很强大&#xff0c;但是实际需求中会遇到各种各样的需求是zxing满足不了的&#xff0c;于是就有了想法自己扩展zxing满足历史遇到的各种需求&#xff0c…

STC单片机启动看门狗定时器介绍和使用

STC单片机启动看门狗定时器介绍 ✨这里以STC8系列为例。 📑看门狗复位(WDT_CONTR) WDT_FLAG:看门狗溢出标志 看门狗发生溢出时,硬件自动将此位置 1,需要软件清零。EN_WDT:看门狗使能位 0:对单片机无影响 1:启动看门狗定时器。 注意:看门狗定时器可使用软件方式启动,…