当前位置: 首页 > news >正文

3.12练习题解

1.台阶问题:

 这道题目一看其实很容易想到可以用dp的板子去做,并且只需要用一维dp即可,其中dp的下标表示到达当前阶梯总共有多少种方法,由于结果有可能会很大所以一定要记得边记录边模,代码实现如下:

#include<bits/stdc++.h>
using namespace std;
const int mod = 100003;
int n,k;
int dp[100010];
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>k;dp[0]=dp[1]=1;for(int i=2;i<=n;i++){for(int j=1;j<=k;j++){if(i>=j){dp[i]=(dp[i]+dp[i-j]) % mod;} }}cout<<dp[n]%mod;return 0;
}

2.递增三元组:

这一道题目的意思是比较好理解的,我们需要考虑的是,由于给的N的极限值是1e5,所以暴力的方式时间复杂度n的三方肯定会爆,于是我们就要考虑如何对时间复杂度进行优化。

我们可以这样进行考虑,由于数组b是中间数组,我们不妨先对三个数组进行排序,然后我们对b进行枚举,对于每一次枚举,我们在a数组中找到所有小于当前枚举对应的b数组下标元素的个数,然后再找到c数组中所有大于当前b数组下标所对应的元素个数,再把当前符合条件的总个数加到ans上面即可。

再继续思考我们对于每次枚举,然后在a,c数组中查找符合要求的,都可以通过二分进行查找从而降低时间复杂度。所以代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;typedef long long LL;
const int N = 1e5+10;
int num[3][N];int main() {int n;scanf("%d", &n);for(int i = 0; i < 3; ++i) for(int j = 1; j <= n; ++j) scanf("%d", &num[i][j]);for(int i = 0; i < 3; ++i)sort(num[i]+1, num[i]+n+1);LL ans = 0;//枚举B,寻找A满足的个数以及C满足的个数相乘for(int i = 1; i <= n; ++i) {int key = num[1][i];//A中二分查找第一个不小于key的数的下标int pos1 = lower_bound(num[0]+1, num[0]+n+1, key)-num[0]-1;//C中二分查找第一个大于key的数的下标int pos2 = upper_bound(num[2]+1, num[2]+n+1, key)-num[2];if(pos1 >= 1 && pos2 <= n) {ans += (LL)pos1*(n-pos2+1);}}cout<<ans<<endl;return 0;
}

这段代码有需要解释的地方:

  1. num[0]+1:这是指向num数组的第一个元素的下一个位置的指针。换句话说,它指向num数组中的第二个元素。
  2. num[0]+n+1:这是指向num数组的最后一个元素的下一个位置的指针。换句话说,它指向num数组之后的第一个位置。
  3. lower_bound(num[0]+1, num[0]+n+1, key):这是在num数组的第二个元素和最后一个元素之间(不包括最后一个元素)查找第一个不小于key的元素的迭代器。
  4. lower_bound(...)-num[0]-1:这将返回的迭代器与num数组的第一个元素的指针相减,然后减去1。这样,我们得到的是找到的元素在num数组中的索引。

所以,pos1存储的是keynum数组中的位置,如果key不在num数组中,则pos1将是key应该插入的位置,以保持num数组的有序性。

简而言之,这段代码在num数组中查找key的位置,并返回其索引。如果key不在数组中,则返回应该插入key的位置。

在C++中,指针的算术运算实际上是对指针所指向的内存地址进行算术运算。当两个指针指向同一个数组或同一个对象的成员时,它们之间的差值表示两个元素之间的偏移量,这个偏移量是以元素为单位,而不是以字节为单位。

对于数组numnum[0]是一个指向数组第一个元素的指针。当我们执行lower_bound函数时,得到的是一个迭代器,它指向数组中第一个不小于key的元素。这个迭代器也是一个指针,指向数组中的某个元素。

当从lower_bound返回的迭代器中减去num[0]时,得到的是两个指针之间的偏移量,这个偏移量表示从数组的第一个元素到找到的元素之间有多少个元素。因为lower_bound返回的迭代器指向的是数组中的元素,而不是元素之间的空隙,所以这个偏移量实际上就是找到的元素在数组中的下标(从0开始计数)。

最后,减去1,是因为我们希望得到的是下标而不是偏移量。在C++中,数组的下标是从0开始的,而指针的偏移量是从1开始的(即,指向第一个元素的指针偏移量为0,指向第二个元素的指针偏移量为1,依此类推)。因此,减去1将偏移量转换为正确的下标。

所以,lower_bound(...)-num[0]-1的结果就是找到的元素在数组中的下标。

第二种方法:双指针优化:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;typedef long long LL;
const int N = 1e5+10;
int num[3][N];int main() {int n;scanf("%d", &n);for(int i = 0; i < 3; ++i) for(int j = 1; j <= n; ++j) scanf("%d", &num[i][j]);for(int i = 0; i < 3; ++i)sort(num[i]+1, num[i]+n+1);LL ans = 0;//枚举B,寻找A满足的个数以及C满足的个数相乘int a = 1, c = 1;for(int i = 1; i <= n; ++i) {int key = num[1][i];while(a<=n && num[0][a] < key) a++;while(c<=n && num[2][c] <= key) c++;ans += (LL)(a-1)*(n-c+1);}cout<<ans<<endl;return 0;
}

其实也就是将二分中的部分更改了一下。

之前的双指针算法时间复杂度的瓶颈为:排序O(nlog2n)
考虑是否可以不排序在O(n)的时间内解决此问题呢?

既然要排序实现快速的查找A中小于B[i]的数的个数,可以将数组A中所有元素出现的次数存入一个哈希表中,因为数组中元素的范围只有n5, 可以开一个大的数组cnta 作为哈希表。

在枚举B中元素时,我们需要快速查找找小于B[i]的所有元素的总数,只需要在枚举之前先将求出表中各数的前缀和即可。

查找C与查找A同理可得。

代码如下:

//前缀和
#include <iostream>
#include <cstdio>using namespace std;typedef long long LL;
const int N = 1e5+10;
int A[N], B[N], C[N];
int cnta[N], cntc[N], sa[N], sc[N];int main() {int n;scanf("%d", &n);//获取数i在A中有cntc[i]个,并对cnt求前缀和safor(int i = 1; i <= n; ++i) {scanf("%d", &A[i]);cnta[++A[i]]++;}sa[0] = cnta[0];for(int i = 1; i < N; ++i) sa[i] = sa[i-1]+cnta[i];//B只读取即可for(int i = 1; i <= n; ++i) scanf("%d", &B[i]), B[i]++;//获取数i在C中有cntc[i]个,并对cnt求前缀和scfor(int i = 1; i <= n; ++i) {scanf("%d", &C[i]);cntc[++C[i]]++;}sc[0] = cntc[0];for(int i = 1; i < N; ++i) sc[i] = sc[i-1]+cntc[i]; //遍历B求解LL ans = 0;for(int i = 1; i <= n; ++i) {int b = B[i];ans += (LL)sa[b-1] * (sc[N-1] - sc[b]);}cout<<ans<<endl;return 0;
}

感谢您的观看。

相关文章:

3.12练习题解

1.台阶问题&#xff1a; 这道题目一看其实很容易想到可以用dp的板子去做&#xff0c;并且只需要用一维dp即可&#xff0c;其中dp的下标表示到达当前阶梯总共有多少种方法&#xff0c;由于结果有可能会很大所以一定要记得边记录边模&#xff0c;代码实现如下&#xff1a; #incl…...

Java中实现双向链表

一、目标 最近项目中实现双向链表&#xff0c;同时转为满二叉树。 二、代码 用java实现双向链表的代码如下&#xff1a; class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { val x; } }public class FullBinaryTree {public TreeNode createTree(int[…...

【DevOps实战之k8s】使用Prometheus和Grafana监控K8S集群

【DevOps实战之k8s】使用Prometheus和Grafana监控K8S集群 目录 【DevOps实战之k8s】使用Prometheus和Grafana监控K8S集群系统架构Kubernetes集群指标抓取指标可视化警告PromQL示例按命名空间统计集群中的Pod数按命名空间重启Pod未就绪的PodCPU过度使用Memory过度使用健康的集群…...

【读论文】【精读】3D Gaussian Splatting for Real-Time Radiance Field Rendering

文章目录 1. What&#xff1a;2. Why&#xff1a;3. How&#xff1a;3.1 Real-time rendering3.2 Adaptive Control of Gaussians3.3 Differentiable 3D Gaussian splatting 4. Self-thoughts 1. What&#xff1a; What kind of thing is this article going to do (from the a…...

JVM理解学习

参考视频 JVM架构总览图 程序计数器 程序计数器&#xff0c;物理上用寄存器实现。 作用&#xff1a; 记住下一条JVM指令的执行地址 特点&#xff1a; 1 是线程私有的&#xff0c;随着线程的创建而创建&#xff0c;随着线程的消息而消息 2 是一小块内存 3 唯一不会内存溢出的地方…...

使用 Ruby 或 Python 在文件中查找

对于经常使用爬虫的我来说&#xff0c;在大多数文本编辑器都会有“在文件中查找”功能&#xff0c;主要是方便快捷的查找自己说需要的内容&#xff0c;那我有咩有可能用Ruby 或 Python实现类似的查找功能&#xff1f;这些功能又能怎么实现&#xff1f; 问题背景 许多流行的文本…...

python实现冒泡排序

冒泡排序是一种简单的排序算法&#xff0c;它重复地遍历要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经排序完成。 以下是用Python实现冒泡排序的代…...

大数据开发(HBase面试真题-卷二)

大数据开发&#xff08;HBase面试真题&#xff09; 1、HBase读写数据流程&#xff1f;2、HBase的读写缓存&#xff1f;3、在删除HBase中的一个数据的时候&#xff0c;它什么时候真正的进行删除呢&#xff1f;4、HBase的一个region由哪些东西组成&#xff1f;5、HBase的rowkey为…...

基于springboot+vue的线上教育系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 现在大家的生活方式正在被计算机的发展慢慢改变着&#xff0c;学习方式也逐渐由书本走向荧幕,我认为这并不是不能避免的,但说实话,现在的生活方式与以往相比有太大的改变&#xff0c;人们的娱乐方式不仅仅…...

01-shell的自学课-基础变量学习

一、echo变量的一个坑 声明【临时变量】&#xff0c;然后打印出来&#xff1b;&#xff08;拓展&#xff1a;env是linux的全局变量&#xff09; [rootgong ~]# xinjizhiwashell [rootgong ~]# echo $xinjizhiwa shell [rootgong ~]# echo $xinjizhiwa-haha shell-haha [rootgo…...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Span)

作为Text组件的子组件&#xff0c;用于显示行内文本的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 该组件从API Version 10开始支持继承父组件Text的属性&#xff0c;即如果子组件未设置…...

前端框架的演进之路:从静态网页到现代交互体验的探索

前端框架的发展史 随着互联网的快速发展&#xff0c;前端技术也在不断进步&#xff0c;前端框架作为前端开发的重要工具&#xff0c;经历了从简单到复杂、从单一到多元的演变过程。本文将回顾前端框架的发展史&#xff0c;探讨其变迁背后的原因和趋势。 一、静态网页时代 在…...

在Linux/Ubuntu/Debian中设置字体

下载字体。 下载你喜欢的字体&#xff0c;双击并安装。 之后更新字体缓存&#xff1a; fc-cache -f -v安装 GNOME 调整。 GNOME Tweaks 是一个工具&#xff0c;允许你自定义 GNOME 桌面环境的各个方面&#xff0c;包括字体。 如果你还没有安装 GNOME Tweaks&#xff1a; …...

Python 常用内置函数,及实例演示

Python的内置函数非常强大&#xff0c;可以帮助你完成各种任务。以下是20个非常有用的Python内置函数及其使用实例&#xff1a; 1. abs() 返回数字的绝对值。 print(abs(-5)) # 输出&#xff1a;52. all() 如果迭代器的所有元素都为真&#xff08;或迭代器为空&#xff09…...

C++标准输入输出和名字空间

C标准输入输出和名字空间 标准输入输出 在C中&#xff0c;标准输入输出&#xff08;I/O&#xff09;是通过标准库中的iostream库来实现的&#xff0c;它提供了一套流&#xff08;stream&#xff09;抽象来进行数据的输入和输出操作。这套流抽象包括输入流用于读取数据&#x…...

hive逗号分割行列转换

select * from ( select back_receipt_nos,order_no,reject_no from ods_oneplus.ods_us_wms_reject_order_match_all_d where order_no 10150501385980001 ) t1 lateral view explode(split(t1.back_receipt_nos, ,)) t as back_receipt_no where 1 1;...

Jenkins插件Parameterized Scheduler用法

Jenkins定时触发构建的同时设定参数。可以根据不同的定时构建器设置不同参数或环境变量的值。可以设置多个参数。并结合when控制stage流程的执行。结合when和triggeredBy区分定时构建的stage和手动执行的stage。 目录 什么是Parameterized Scheduler&#xff1f;如何配置实现呢…...

西门子S7.NET通信库【读】操作详解

在使用西门子PLC进行工业自动化控制的过程中&#xff0c;经常需要与PLC进行数据交换。S7.NET是一款广泛应用于.NET平台的西门子PLC通信库&#xff0c;它为开发者提供了一系列的API函数&#xff0c;以便在C#、VB.NET等.NET语言中轻松实现与西门子PLC的数据交互。本文将详细介绍如…...

Qt/C++音视频开发69-保存监控pcm音频数据到mp4文件/监控录像/录像存储和回放/264/265/aac/pcm等

一、前言 用ffmpeg做音视频保存到mp4文件&#xff0c;都会遇到一个问题&#xff0c;尤其是在视频监控行业&#xff0c;就是监控摄像头设置的音频是PCM/G711A/G711U&#xff0c;解码后对应的格式是pcm_s16be/pcm_alaw/pcm_mulaw&#xff0c;将这个原始的音频流保存到mp4文件是会…...

闲聊Swift的枚举关联值

闲聊Swift的枚举关联值 枚举&#xff0c;字面上理解&#xff0c;就是把东西一件件列出来。 在许多计算机语言中&#xff0c;枚举都是一种重要的数据结构。使用枚举可以使代码更简洁&#xff0c;语义性更强&#xff0c;更加健壮。 Swift语言也不例外。但和其他语言相比&#xf…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...