尺取法(图文解析、初学推荐)

2023-05-16

文章目录

        • 最少连续页(poj3320)
          • 分析题意
            • 第一步:找第一个满足条件区间
            • 第二步:开始将左端边界向右移,达到“缩小”区间、减少连续页的目的。
          • 归纳总结代码

尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧,一般用于求取有一定限制的区间个数或最短的区间等等。当然任何技巧都存在其不足的地方,有些情况下尺取法不可行,无法得出正确答案,所以要先判断是否可以使用尺取法再进行计算。

本人为一名普通二本学校自动化专业的大二学生,对编程有着少许兴趣。
最近想了解什么是尺取法,于是想写道简单尺取法相关的题目,当练一练手。

最少连续页(poj3320)

题意:一本书有P页,每一页都一个知识点,求去最少的连续页数覆盖所有的知识点。

样例
输入:
6
1 1 3 1 2 3
输出:
3
备注:一本书有6页,第一页知识点为1…第6页知识点为3。

分析题意

按照尺取法的定义:一种高效的枚举区间的方法。我们应该先在找一个满足条件的区间(不一定是最优),然后再通过将左边界向右移、右边界向右移的方式需找最优区间。

第一步:找第一个满足条件区间

为了能够更好地找到最优区间,我们需要先了解有多少个不同的知识点、在已读的页数中每个知识点出现了几次。

map <int, int> cnt;
set <int> t;
//set主要是统计不同的知识点
//set不允许重复插入 每个元素都是不同的 
//用map记录每个知识点在连续页中出现的次数 

①:可以用set容器“不能重复插入”的特性,统计书中出一共有多少个不同的知识点。
插入情况

    for (int i = 0; i < p; i++)
	{ 
		scanf("%d", &a[i]);
		t.insert(a[i]);
	}
    int num = t.size();

插入个数 num=3
②:可以用map容器“映射”的特性,统计出在已读的页数中相同知识点出现次数。
映射

        while (end<p && sum<num)
        {  
        	//选取不同知识点 
            if (cnt[a[end]] == 0) 
				sum++;
			cnt[a[end]]++;
        	end++;
        } 
第二步:开始将左端边界向右移,达到“缩小”区间、减少连续页的目的。

begin:左边界下标 end:右边界下标
ans:当前已读最少连续页

在满足条件的区间里
如果右边界下标减去左边界下标小于当前已读最少连续页。
那么右边界下标减去左边界下标就是当前最少页数。
如果end-begin<ans,则ans=end-begin+1。

初始状态(第一个满足条件区间)
初始状态
当前状态:begin=0 end=4 ans=5
begin右移
当a[0]知识点在已读页数出现过,则将左边界向右移,右边界不变。
当前状态:begin=1 end=4 ans=4
begin右移
当a[1]知识点在已读页数出现过,左边界向右移,右边界不变。
当前状态:begin=2 end=4 ans=3
begin右移
当a[2]知识点在已读页数未出现过右边界要向右移,找到满足条件的区间。
当前状态:begin=3 end=4 ans=3
end右移
end右移
当前状态:begin=1 end=5 ans=3
begin右移
右边界找到合适位置后,左边界再向右移。
此时a[3]知识点在已读页数未出现过右边界要向右移,找到满足条件的区间。可是右边界已经到达最后一页,结束查找。
最终得到最少页数为3。

    while (1)
	{	
		//begin:左边界  end:右边界 
		//num不同的知识点 sum已读知识点 
        while (end<p && sum<num)
        {  
        	//选取不同知识点 
            if (cnt[a[end]] == 0) 
				sum++;
			cnt[a[end]]++;
        	end++;
        } 
        
        //读完了,退出循环 
        if (end==p) break;
        
        //判断有没有更小的连续页  
        if(ans>end-begin)
        	ans = end-begin;
        //ans=end-begin
		//因为end在上面循环中多加了一个1 
        	
        //向前推 
        cnt[a[begin]]--;
		if(cnt[a[begin]]==0)
			sum--; 
		begin++;
    }
归纳总结代码

通俗版

//通俗版
#include <bits/stdc++.h>
#include<algorithm>
#include <set>
#include <map>
#define MAX 1000010
#define ll long long
#define INF 1000010
using namespace std;
int a[MAX];
map <int, int> cnt;
set <int> t;

int main()
{
   int p, ans = INF, begin=0, end=0, sum=0;
   scanf("%d", &p);
   for (int i = 0; i < p; i++)
   { 
   	scanf("%d", &a[i]);
   	t.insert(a[i]);
   }
   int num = t.size();
   while (1)
   {	
       while (end<p && sum<num)
       {   
           if (cnt[a[end]] == 0) 
   			sum++;
   		cnt[a[end]]++;
       	end++;
       } 
       
       if (end==p) break;
       if(ans>end-begin)
       	ans = end-begin;
       cnt[a[begin]]--;
   	if(cnt[a[begin]]==0)
   		sum--; 
   	begin++;
   }
   cout<<ans<<endl;
   return 0;
}

精简版(来源网上)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
#include <map>
#define MAX 1000010
#define LL long long
#define INF 0x3f3f3f3f
 
using namespace std;
int a[MAX];
map <int, int> cnt;
set <int> t;
int p, ans = INF, st, en, sum;
 
int main()
{
    scanf("%d", &p);
    for (int i = 0; i < p; i++) scanf("%d", a+i), t.insert(a[i]);
    int num = t.size();
    while (1){
        while (en<p && sum<num)
            if (cnt[a[en++]]++ == 0) sum++;
        if (sum < num) break;
        ans = min(ans, en-st);
        if (--cnt[a[st++]] == 0) sum--;
    }
    printf("%d\n", ans);
    return 0;
}

希望能够将自己的一些学习经验分享给有需要的人。
我是小郑,一个坚持不懈的小白。
博客参考链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尺取法(图文解析、初学推荐) 的相关文章

  • Redis内部数据结构详解(4)——ziplist

    本文是 Redis内部数据结构详解 系列的第四篇 在本文中 xff0c 我们首先介绍一个新的Redis内部数据结构 ziplist xff0c 然后在文章后半部分我们会讨论一下在robj dict和ziplist的基础上 xff0c Red
  • golang是如何实现高并发的?深入领会MPG模式

    多线程共享内存 xff0c 这也是Java C 或者C 43 43 等语言中的多线程开发的常规方法 xff0c 其实golang语言也支持这种传统模式 xff0c 另外一种是Go语言特有的 xff0c 也是Go语言推荐的 xff1a CSP
  • Mysql索引类型Btree和Hash的区别以及使用场景

    遇到单表数据量大的时候很多开发者都会想到给相对的字段建立索引来提高性能 xff08 mysql索引的使用 xff09 xff0c 但很少会去关注索引的类型该如何选择 xff0c 在mysql中支持有两种类型 xff0c 最常用的也是默认的B
  • tcpreplay的安装使用

    转自 xff1a https www cnblogs com zlslch p 7325599 html utm source 61 itdadao amp utm medium 61 referral tcpreplay是什么 xff1f
  • Ubuntu18.04从零配置到zed2i实现,orb-slam3运行,ros安装(Ubuntu18.04 3050ti) 系列一:cuda与csdnn安装。

    利用双系统来安装Ubuntu18 04 采用的是U盘烧录镜像 xff0c 硬盘为980 256G 目录 1 烧录镜像以及分区 2 设置ubuntu密码 3 网络认证 4 更新显卡驱动以及软件源 5 安装搜狗输入法 6 安装vpn 7 安装C
  • java ee 话外之 http

    HTTP请求格式 当浏览器向web服务器发出请求时 xff0c 它向服务器传递了一个数据块 xff0c 也就是请求信息 xff0c http请求信息由三个部分组成 1 请求方法 url协议 版本 2 请求头 xff08 request he
  • Pytorch学习(3) —— nn.Parameter nn.ParameterList nn.ParameterDict 源码解析

    为了更好理解Pytorch基本类的实现方法 xff0c 我这里给出了关于参数方面的3个类的源码详解 此部分可以更好的了解实现逻辑结构 xff0c 有助于后续代码理解 xff0c 学pytorch的话这个不是必须掌握的 xff0c 看不懂也没
  • 针对电陶炉E5错误的维修总结(狗头)

    一个编程技术员开始研究电陶炉维修是不是有些奇怪 没办法 xff0c 最近家里面各种电器都开始坏掉了 xff0c 有的是按钮 xff0c 有的是断线 xff0c 有的就是电路板内部故障 固件坏了买相应零件修好就能用 xff0c 比如用4个开关
  • 关于视觉SLAM十四讲sophus库安装报错

    Sophus安装 xff1a git clone https github com strasdat sophus git cd sophus mkdir build cmake make 这时候系统报错 error lvalue requ
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)

    最近一些人问我怎么在BPU上部署yolov5 xff0c 因为之前的博客 BPU部署教程 一文带你轻松走出模型部署新手村介绍的网络都是基于Caffe的 xff0c 自己的网络都是基于pytorch的 xff0c 所以遇到了很多坑 鉴于这些需
  • 在旭日X3派开发板上使用USB Wifi来提高网络速度

    对于我来说 xff0c 开发板自带的wifi模块速度不是很满意 xff0c 下载或者传文件啥的最多也就2M s 而且 xff0c 在之前测评博客 首发 多方位玩转 地平线新发布AIoT开发板 旭日X3派 Sunrise x3 Pi 插电 x
  • 体验极速——在旭日X3派上使用双频1300M USB无线网卡

    上一篇博客 在旭日X3派开发板上使用USB Wifi来提高网络速度 提供一种低成本 xffe5 20的USB Wifi解决方案 这个模块的传输速度在10M s以内 xff0c 尽管满足正常的开发需求 xff0c 但在项目应用时 xff0c
  • linux深度学习服务器搭建——CUDA与cuDNN的选择与安装

    前言 本文章参考实验室师妹的文章Ubuntu14 04 43 CUDA8 0 43 Opencv3 1 43 Anaconda2 43 Caffe安装 xff0c 最近安装最新版时候遇到不少坑 xff0c 下面就介绍下如何去安装CUDA和c
  • 卷积神经网络处理Cifar-10分类数据集

    Cifar 10分类数据集 Cifar 10分类数据集简介 CIFAR 10数据集由10个类的60000个32x32彩色图像组成 xff0c 每个类有6000个图像 有50000个训练图像和10000个测试图像 数据集分为五个训练批次和一个
  • STM32和ROS串口通信常见问题汇总答疑

    STM32和ROS串口通信常见问题汇总答疑 大家好 我是白茶清欢 最近看了博客文章 stm32和ros的串口通信 有很多问题的评论 这里汇总回复一下 问题1 运行时报错如下 rosrun topic example publish node
  • 无人机导航中常见的坐标系

    无人机导航中常见的坐标系包括 xff1a 地球中心坐标系 ECEF EarthCenteredEarthFixedCoordinateSystem xff0c ECEF WGS 84大地坐标系 WorldGeodeticCoordinate
  • DEVC++(1)单文件实现重载运算符的十六进制数类

    本文运用DEVC 43 43 软件 xff0c 通过C 43 43 类的定义和重载运算符来实现十六进制数类的运算操作 xff0c 代码以单文件的方式来构建 题目描述如下 xff1a 设计1 4位的无符号十六进制数据类class HEX 可以
  • Jetson Nano – UART

    There is a UART on the J41 GPIO Header of the NVIDIA Jetson Nano Developer Kit Useful when you need a little bit of extr
  • 关于thinkbook14+以及16+安装ubuntu22.04 LTS后WIFI问题

    首先 xff0c 介绍一下电脑配置 购买的是2022款Thinkbook14 43 R7 6800H锐龙核显版 Intel的也一样可以用 1 设置bios 点击开机键后疯狂按F1打开BIOS xff0c 将security boot设置为d
  • RTC可调节时钟

    此代码只可显示小时 分钟 xff0c 大家可以参考并写出秒甚至年月日的相关操作代码 rtc h ifndef RTC H define RTC H 时间结构体 typedef struct vu8 hour vu8 min vu8 sec

随机推荐

  • C语言中关于float、double、long double精度及数值范围理解

    转自 xff1a http blog sina com cn s blog 6ebd49350101gdgo html IEEE754 浮点数的表示方法 C 语言里对 float 类型数据的表示范围为 3 4 10 38 xff5e 43
  • 移动机器人系列----->前言

    移动机器人系列 gt 前言 准备开始写移动机器人相关的文章 初步的想法是做一个能够实现室内自主定位导航的移动机器人 xff0c 通过写这一系列的文章来记录和探讨学习过程中的问题 xff08 这是一篇立flag的文章 xff0c 希望不会立马
  • 移动机器人系列----->框架开篇

    移动机器人系列 gt 框架开篇 1 xff1a 框架浅聊 这次项目的重点是实现移动机器人的定位建图以及路径规划算法 xff0c 底盘硬件部分不过多的进行展开 下图是项目简单的硬件框架示意图 xff08 1 xff09 为节约时间 xff0c
  • 移动机器人系列----->树莓派4B测试ORB-SLAM2

    移动机器人系列 gt 树莓派4B运行测试ORB SLAM2 注 测试平台为树莓派4B xff08 8 43 32G xff09 1 xff1a 树莓派安装ubuntu18 04及编译ORB SLAM2 1 1 xff1a 树莓派上安装ubu
  • PX4飞控之自主返航(RTL)控制逻辑

    本文基于PX4飞控1 5 5版本 xff0c 分析导航模块中自护返航模式的控制逻辑和算法 自主返航模式和导航中的其他模式一样 xff0c 在Navigator main函数中一旦触发case vehicle status s NAVIGAT
  • MATLAB的MCC命令

    mcc函数将matlab的m文件转化为c c 43 43 文件 mcc函数命令格式 xff1a mcc option fun fun2 mexfile1 mlifile 函数作用 xff1a 将matlab程序中的fun m转化为fun c
  • STM32 | 分享自定义协议的一些典型例子

    1024G 嵌入式资源大放送 xff01 包括但不限于C C 43 43 单片机 Linux等 关注微信公众号 嵌入式大杂烩 xff0c 回复1024 xff0c 即可免费获取 xff01 上次分享的 分享一个很酷的上位机软件 中 xff0
  • 基于TCP/IP和UDP协议的socket编程结构解析

    1 套接字 xff08 socket xff09 socket起源于Unix xff0c 而Unix Linux基本哲学之一就是 一切皆文件 xff0c 都可以用 打开open gt 读写write read gt 关闭close 模式来操
  • printf 函数实现的深入剖析[转载]

    研究printf的实现 xff0c 首先来看看printf函数的函数体 xff01 int printf const char fmt int i char buf 256 va list arg 61 va list char amp f
  • Altium Designer(AD20)画PCB时ctrl键、shift键、鼠标按键的妙用

    ctrl键的妙用 1 绘画窗口放大缩小 按住ctrl键 43 滚动鼠标滚轮 xff0c 滚前放大 xff0c 滚后缩小 2 高亮 按住ctrl键 43 鼠标点击有网络信号的焊盘 过孔 线 xff0c 便高亮该网络 xff0c 其他网络变暗或
  • PyQt结合Opencv显示图片以及摄像头

    环境 xff1a python3 7 PyQt5 11 3 OpenCV python4 0 0 21 Pycharm 2018 2 2 1 通过PyQt与OpenCV显示图片 import sys import cv2 import nu
  • allegro更新铜皮方法和快捷键

    前景 xff1a 在如今时代 xff0c allegro软件是三大PCB设计软件之一 xff0c 不少知名公司都要求会allegro软件 xff0c 所以很多PCBlayout工程师开始转用allegro xff0c 同时也出现很多新手学a
  • Allegro快捷键(env)位置和快捷键设置

    前景 在画PCB板 xff0c 保证质量同时 xff0c 也要讲究效率 xff0c 要是一只手用鼠标来点选命令画板 xff0c 效率会大大折扣 xff0c 所以出现PCBlayout快捷键 xff0c 本文章将的是allegro快捷键 al
  • Altium Designer使用者,你想要一键出Gerber吗?

    前言 在我们辛辛苦苦画完一个PCB板 xff0c 细心谨慎地生成Gerber xff0c 突然 xff0c 发现一个丝印没摆好 xff0c 只能改丝印再重新生成Gerber xff0c 又突然 xff0c 发现有根线离电源太近了 xff0c
  • allegro同比例放大缩小LOGO丝印

    前言 在遇到元件密集情况下 xff0c 既要兼顾元件位号丝印 xff0c 又能凸显公司的LOGO时 xff0c 常常碰到LOGO丝印太大 xff0c 放不下 xff0c 要是再缩小一点 xff0c 就能放下了 所以我就写了这篇文章 xff0
  • 利用Sigrity的SPEED2000进行时域电源噪声分析

    前序 相信大家在网上可以找到本文章的类似教程 xff0c 我就是这样 xff0c 找到了教程 xff0c 兴致冲冲地按教程每个步骤操作 xff0c 但最后因为素材不一样 xff0c 得不到想要的结果 xff0c 有时出来的波形是一条水平线
  • 利用Sigrity PowerDC进行单板直流仿真--静态功率传输体系分析

    前序 本文章利用Sigrity PowerDC进行单板直流仿真 静态功率传输体系分析的教程写出来 xff0c 同时 xff0c 将Sigrity PowerDC 单板直流仿真分析素材上传 xff0c 供大家使用 xff0c 不用苦苦寻找仿真
  • org.htmlparser小结

    org htmlparser 主要用来解析HTML网页 一 基本上HTML中的每个标签对应于一个类 xff0c 例如 xff1a p标签对应于ParagraphTag类 ul标签对应于BulletList类 li标签对应于Bullet类 a
  • STM32中使用printf打印串口数据

    STM32使用printf打印串口 摘要 该方法适用于 STM32 xff0c 实现了使用 printf 等标准 C 流函数输出数据的办法 xff0c 极大的减少了输出串口数据时所需要做的数据处理 实现原理 在 C 库中 xff0c pri
  • 尺取法(图文解析、初学推荐)

    文章目录 最少连续页 xff08 poj3320 xff09 分析题意第一步 xff1a 找第一个满足条件区间第二步 xff1a 开始将左端边界向右移 xff0c 达到 缩小 区间 减少连续页的目的 归纳总结代码 尺取法 xff1a 顾名思