1236. 递增三元组:做题笔记

目录

暴力

代码

二分

代码

前缀和 

代码

推荐视频讲解


暴力

这道题说的是有三个元素数量相同的数组,想知道有多少个三元组满足:三个数分别来自 A B C数组且呈现递增。

我想的是既然要求递增,那就先把数组数据都排一下序,直接sort函数用起来。因为排了序的话就说明在某个数之后的所有数都是满足条件的,直接进行累加就可以。

第一个数A数组肯定要先遍历一下的(是的我当时做的时候压根没想到其他的),我就想着我们既然想利用排完序的好处,那就从这想。

在第一层循环的基础上,在对第二层数据挑选的时候,就可以利用二分找到我们上面所说的“某个数”,这里的某个数其实也就是当前B数组里第一个大于当前外层循环正在处理的A数组的这个元素,我们知道在这个数之后的B数组中的数都是一种选择的可能。同理,到了最内层对从C数组中选的第三个数的可能性也就是在前两个数确定的这种情况下满足条件的可能性。

这样就枚举了所有可能性,肯定超时的。且这样的写法一个数据都过不了呜呜😭

我就没想到到底怎么优化掉第二层循环,,

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N],b1[N],c1[N];
int n;
int find(int q[],int x)
{int l=0,r=n;while(l<r){int mid=(l+r)/2;if(q[mid]>x)r=mid-1;else l=mid;}if(q[l]>x)return l;else if(q[l]==x)return l+1;else return -1;
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];for(int i=0;i<n;i++)cin>>c[i];sort(a, a+n);sort(b, b+n);sort(c, c+n);int cnt=0;for(int i=0;i<n;i++){for(int j=find(b,a[i]);j<n;j++){//第三层循环还是好优化的(不过没什么卵用,因为双层循环仍然tle😜)/*for(int k=find(c,b[j]);k<n && k!=-1;k++){cnt++;}*/int k=find(c,b[j]);cnt+=n-k;}}cout<<cnt;return 0;} 

二分

就是看了讲解才知道我们想降成一层循环,那留下来的这层循环就必须是中间的B数组。

因为A B C 三元组想递增嘛,那 A<B,C>B。遍历B数组每个元素,可以通过二分找到A数组中第一个大于当前B数组中元素的数的位置,和C数组中第一个大于当前B数组中元素的数的位置,通过元素总数与该位置的相减,得到其中间的元素个数。

我们可以写二分模板,也可以使用 lower_bound和upper_bound 函数,感觉直接用函数很方便。就像那个sort函数一样。

由于这两个函数的操作对象应该是有序的,我们需要对数组进行排序。

补充一下这两个函数的用法:

lower_bound(begin, end, value):在从小到大排好序的数组中,在数组的 [begin, end) 区间中二分查找第一个大于或等于value的数,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标


upper_bound(begin, end, value):在从小到大排好序的数组中,在数组的 [begin, end) 区间中二分查找第一个大于value的数,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。


这两个函数的时间复杂度都是O(logN),其中N是搜索空间中的元素数量。 

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N];
int n;
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];for(int i=0;i<n;i++)cin>>c[i];sort(a, a+n);sort(b, b+n);sort(c, c+n);int cnt=0;for(int i=0;i<n;i++){int l=lower_bound(a,a+n,b[i])-a,r=n-(upper_bound(c,c+n,b[i])-c);cnt+=l*r;}cout<<cnt;return 0;}

l 是数组 a 中小于 b[i] 的元素的数量,r 是数组 c 中大于 b[i] 的元素的数量。

前缀和 

这里前缀和的思路也是以B数组的遍历为主。

记录下所有数字出现的次数,预处理出前缀和,对A C数组进行排序,与B数组当前处理的元素进行比较,通过前缀和的运算得到A数组小于当前元素的个数,和C数组大于当前元素的个数,将这两个数相乘,并随着B数组的遍历对每一种情况进行累加得到最终结果。

关于前缀和的运算:A数组想得到小于当前元素的个数,直接b[i]-1的前缀和得到的就是想要的区间的前缀和  ( sa[b[i]-1] )

C数组想得到大于当前元素的个数,用 N 处的前缀和减去b[i]当前元素的前缀和即可( sc[N]-sc[b[i]] )

需要注意的是,由于数组中每个元素的数据范围是0-1e5,因此在前缀和计算中要从0开始,循环1e5次,关于数组越界问题:

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N];
int a1[N],c1[N];//存放每个数出现次数
int sa[N],sc[N];//计算a1,c1的前缀和
int as[N],cs[N];//通过前缀和的运算处理出所有可能的情况
//as代表比b[i]小的数的个数  cs代表比b[i]大的数的个数
int n;
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];for(int i=0;i<n;i++)cin>>c[i];for(int i=0;i<n;i++)a1[a[i]]++;for(int i=0;i<=N;i++)sa[i]=sa[i-1]+a1[i];for(int i=0;i<n;i++)as[i]=sa[b[i]-1];for(int i=0;i<n;i++)c1[c[i]]++;for(int i=0;i<=N;i++)sc[i]=sc[i-1]+c1[i];for(int i=0;i<n;i++)cs[i]=sc[N]-sc[b[i]];int cnt=0;for(int i=0;i<n;i++){cnt+=as[i]*cs[i];}cout<<cnt;return 0;}

推荐视频讲解

【蓝桥杯真题,递增三元组,前缀和问题】

老师讲的很清晰。推荐观看

AcWing 1236. 递增三元组(三种算法+胎教注释)​​​​​​​

这个题解不知道大家能看到不能。


感觉思路理解还行,但是就是明白了思路到写对题之间还有很长距离,好多细节问题emm. 

哎好难🥀🥀🥀🥀

有问题欢迎指出,一起加油!!!!

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

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

相关文章

springCloudAlibaba集成gateWay实战(详解)

一、初识网关&#xff1f; 1、网关介绍 ​ 在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话…

【opencv】教程代码 —features2D(8)AKAZE 特征点匹配和图像拼接

graf1.png graf3.png <?xml version"1.0"?> <opencv_storage> <H13 type_id"opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>7.6285898e-01 -2.9922929e-01 2.2567123e02…

matlab碰撞检测

文章目录 碰撞对象collisionCylindercollisionBoxcollisionMeshcollisionSpherecollisionCapsulecheckCollisionfitCollisionCapsuleshowCollisionArraycapsuleApproximationaddCapsuleremoveCapsuleconvertToCollisionMesh碰撞对象 函数功能checkCollision检测两几何体是否存在…

前端之CSS——网页的皮肤!!

目录 一、CSS简单介绍 二、css内容 2.1 css的编写方式 2.2 css选择器 2.3 样式属性 2.4 css包围盒 2.5 css中的display 2.6 css中的定位 2.7 css中的浮动与清除 2.7 弹性容器 2.8 字体图标 2.9 …

1.5编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。

1、编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。 package com.kangning.web.controller.system;import java.util.Scanner;/*** 编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。*/ public class CountArea {public static void main(String[] args) …

面向对象编程中的StringBuffer类详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

【Linux 驱动基础】设备树驱动

# 前置知识 在图中&#xff0c;树的主干就是系统总线&#xff0c; IIC 控制器、 SPI 控制器等都是接到系统主线上的分支。其中 IIC1 上接了 AT24C02这个 IIC 设备&#xff0c; DTS 文件的主要功能就是按照图所示的结构来描述板子上的设备信息。 1. Device格式 DTS文件格式 …

【论文阅读】ELA: Efficient Local Attention for Deep Convolutional Neural Networks

&#xff08;ELA&#xff09;Efficient Local Attention for Deep Convolutional Neural Networks 论文链接&#xff1a;ELA: Efficient Local Attention for Deep Convolutional Neural Networks (arxiv.org) 作者&#xff1a;Wei Xu, Yi Wan 单位&#xff1a;兰州大学信息…

基于架构的软件开发方法_1.概述和相关概念及术语

1.体系结构的设计方法概述 基于体系结构的软件设计&#xff08;Architecture-Based Software Design&#xff0c;ABSD&#xff09;方法。ABSD方法是由体系结构驱动的&#xff0c;即指由构成体系结构的商业、质量和功能需求的组合驱动的。 使用ABSD方法&#xff0c;设计活动可以…

C++项目——集群聊天服务器项目(十一)服务器异常退出与添加好友业务

本节来实现C集群聊天服务器项目中的服务器异常退出与添加好友业务&#xff0c;一起来试试吧 一、服务器异常退出 在Linux环境下&#xff0c;我们在服务器端使用CTRLC结束程序执行&#xff0c;即使用CTRLC让服务器异常退出&#xff0c;这样的后果是本应登录服务器的用户在数据库…

vsCode 刷 leetcode 使用 Cookie 登录

1. 安装插件 打开 vsCode&#xff0c;选择扩展&#xff0c;搜索 leetcode&#xff0c;选择第一个&#xff0c;带有中文力扣字样&#xff0c;安装后重启 2. 切换终端 插件安装成功之后&#xff0c;侧边栏选择 leetcode 菜单&#xff0c;切换终端&#xff0c;选择中文版本&…

海康摄像头插件嵌入iframe时视频播放插件位置问题

参考&#xff1a;https://juejin.cn/post/6857670423971758094 原因&#xff1a;没有按照iframe相对位置计算视频插件位置。 解决&#xff1a; $(window).on(resize, resize);function resize(){// 解决iframe中嵌入海康插件初始化问题:// 1. 获取iframe相比于窗口的偏移量;c…

Flutter仿Boss-2.启动页、引导页

简述 在移动应用开发中&#xff0c;启动页和引导页是用户初次接触应用时的重要组成部分&#xff0c;能够提升用户体验和导航用户了解应用功能。本文将介绍如何使用Flutter实现启动页和引导页&#xff0c;并展示相关代码实现。 启动页 启动页是应用的第一个页面&#xff0c;首…

Jenkins首次安装选择推荐插件时出现”No such plugin cloudbees-folder”解决方案

安装Jenkins成功之后&#xff0c;首次启动Jenkins后台管理&#xff0c;进入到安装插件的步骤&#xff0c;选择"推荐安装"&#xff0c;继续下一步的时候出现错误提示&#xff1a; 出现一个错误 安装过程中出现一个错误&#xff1a;No such plugin&#xff1a;cloudb…

【大数据存储】实验二 HDFS操作实验

实验二 HDFS操作实验 启动Hadoop&#xff0c;执行jps&#xff0c;检查Hadoop相关进程是否启动成功 启动hadoop 执行jps,可以看到名称节点和数据节点&#xff0c;第二名称节点都打开了&#xff0c;则hadoop相关进程启动成功 在本地文件系统“/home”下新建两个文件夹&#xff…

Dapr(一) 基于云原生了解Dapr

(这期先了解Dapr&#xff0c;之后在推出如何搭建Dapr&#xff0c;以及如何使用。) 目录 引言&#xff1a; Service Mesh定义 Service Mesh解决的痛点 Istio介绍 Service Mesh遇到的挑战 分布式应用的需求 Multiple Runtime 理念推导 Dapr 介绍 Dapr 特性 Dapr 核心…

前后台分离nodejs+vue租房信息网站express-94sk3.

本租房管理系统有管理员&#xff0c;租客&#xff0c;屋主三个角色。管理员功能有个人中心&#xff0c;租客管理&#xff0c;屋主管理&#xff0c;房源信息管理&#xff0c;订单信息管理&#xff0c;屋主申诉管理&#xff0c;通知公告管理&#xff0c;留言板管理&#xff0c;系…

Electron的学习

目录 项目初始化可以看官网非常详细根路径创建.vscode文件夹主进程和渲染进程之前的通信ipcRenderer.send和ipcMain.on的使用ipcRenderer.invoke和ipcMain.handle的使用 切换主题模式文件拖放保存消息通知进度展示图标闪烁自定义菜单自定义右键菜单 项目初始化可以看官网非常详…

基于PSO优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 5…

如何将平板或手机作为电脑的外接显示器?

先上官网链接&#xff1a;ExtensoDesk 家里有一台华为平板&#xff0c;自从买回来以后除了看视频外&#xff0c;基本没什么作用&#xff0c;于是想着将其作为我电脑的第二个屏幕&#xff0c;提高我学习办公的效率&#xff0c;废物再次利用。最近了解到华为和小米生态有多屏协同…