蓝桥杯--快排+队列+尺取法

news2024/11/10 13:04:10

😃这只松鼠如约而至 - 许嵩 - 单曲 - 网易云音乐 

😃你买菜吗玫瑰 - 要不要买菜 - 单曲 - 网易云音乐 

😃一起玩吧这世界那么多人(电影《我要我们在一起》主题曲) - 莫文蔚 - 单曲 - 网易云音乐 

前言

这是我在CSDN做算法技能树遇到的第一个卡点,接着又在POJ找了道类似题目,挺综合的

刚好学了快排,队列尺取法(也叫双指针,是一种算法思想,用的原理就是队列),就练练手呗

杰西卡是日志统计的进阶版本

日志统计

题目1地址:(代码选择题,数据量达10^5)

日志统计-蓝桥杯-基础-CSDN算法技能树

题目 

如果填空题 --> 代码题,我们该怎么做呢

 

思路

1,

注意!!  时间D的区间[T, T + D),是左闭右开的,所以代码第25行是 >= d

2,

结构体联系时刻ts和编号id

flag数组记录热帖

num数组记录某个帖子时间D内赞的数量

3,

核心代码是第23~30行,已知排序后时间ts从小到大

第23行:遍历

第24行:编号为a[i].id的帖子获赞数+1

第25行:若右边界时间 - 左边界时间 >= d(i"指针"走在前,j"指针"走在后)

第26行:取消左边界帖子获赞

第27行:左边界右移(有队列出队那味了)

第29行:若时间 [i - d, i) 上帖子 a[i].id 获赞数达k

第30行:flag数组标记热帖

代码

#include<iostream>
#include<cstdio> //scanf()
#include<algorithm> //sort()
using namespace std;
const int N = 100010;
int flag[N], num[N]; //记录热帖和获赞数
struct good
{
    int ts, id;
};
bool cmp(good x, good y)
{
    return x.ts < y.ts; //时间从小到大排序
}
int main()
{
    struct good a[N];
    int n, d, k; //数量,时间,获赞
    scanf("%d%d%d", &n, &d, &k);
    for(int i = 0; i < n; ++i)
        scanf("%d%d", &a[i].ts, &a[i].id);
    sort(a, a + n, cmp);
    for(int i = 0, j = 0; i < n; ++i) {
        num[a[i].id]++;
        if(a[i].ts - a[j].ts >= d) {
            num[a[j].id]--; //取消左边界的获赞
            j++; //左边界右移
        }
        if(num[a[i].id] >= k) //时间[i-d, i)上达k个赞
            flag[a[i].id] = 1;
    }
    for(int i = 0; i < n; ++i)
        if(flag[i] == 1) //注意这里是i,不是a[i].id
            printf("%d\n", i);
    return 0;
}
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
1
3

杰西卡的阅读问题

  不容易,POJ上百万用户,只有4700人做过这道题

还-有-700-人-做-不-出-来

 一点一点看ACM大佬们0注释的代码(地图,哈希,二分,双队列,STL库,动不动一两百行)有些语法让人一头雾水

所幸思路有了,就可以找自己会的代替办法

POJ和ACM一样,就算Accpted 90%也是WA

第一次测试数据过了, 没用cin, 也没用STL库(sort(), min()),WA!!!!!!!!!!!!

第二次,找了半小时,在讨论区找了6组数据,解决了个小bug,Runtime Error!!!!!!!!!!!!!!!!!!!!!!!!

第三次,CSDN提问题解决了,感谢CSDN

最终AC😀

讨论区说不要用STL库的内容,比如min(), sort(),用了就过不了,必须自己写 

题目2地址:(浏览器可翻译)(数据量++,达10^6)

3320 -- Jessica's Reading Problem (poj.org)

题目

杰西卡必须掌握一本非常厚的教科书中包含的所有想法,该教科书有些想法不止一次被涵盖

杰西卡认为,如果她设法至少阅读一次每个想法,她就可以通过考试

她决定只阅读本书的一个连续部分,其中包含整本书涵盖的所有思想

当然,子书应该尽可能薄

每个想法都使用一个 ID 进行编码,该 ID 是一个非负整数

输入

输入的第一行是整数P(1≤P1000000),这是杰西卡教科书的页数。第二行包含 P 个非负整数,描述每个页面的想法。第一个整数是第一页的内容,第二个整数是第二页的内容,依此类推

假设出现的所有整数都可以很好地适应有符号的 32 位整数类型(这就是代码1数组b越界的原因!!)

输出

输出一行:包含所有书中所有想法的最短连续部分的页数

输入例子

5
1 8 8 8 1

输出例子

2

也就是求,所有数字都包括在队列中的最小连续页数,或者说最短区间 

考察

1,队列

2,快排

3,scanf()比cin快 

4,尺取法

5,如何判断尺取法所取的片段,包括了所有元素?

关于队列:

《啊哈算法》第二章栈,队列,链表(解析+代码)_码龄11天的博客-CSDN博客

队首删除一个数的操作是:head++;

队尾增加一个数的操作是:q[tail] = x; tail++;

关于快排:

C++快速排序之整型数组_码龄11天的博客-CSDN博客_c++整数排序

让我再手写一次快排

void quick_sort(int left, int right, int a[])
{
    if(left >= right) return;
    int i, j, base;
    i = left, j = right, base = a[left];
    while(i < j) {
        while(i < j && a[j] >= base) j--;
        while(i < j && a[i] <= base) i++;
        if(i < j) {
            a[i] = a[i]^a[j];
            a[j] = a[i]^a[j];
            a[i] = a[i]^a[j]; //异或交换两数
        }
    }
    a[left] = a[j]; //左端与i,j指向元素交换
    a[j] = base;
    quick_sort(left, j - 1, a); //递归左边
    quick_sort(j + 1, right, a); //递归右边
}

关于scanf():

cin关闭流同步的利弊与cout的endl使用_光風霽月的博客-CSDN博客_为什么不关cin

关于尺取法:

尺取法是算法竞赛中,常用的优化技巧 

 尺取法(图文解析、初学推荐)_小白小郑的博客-CSDN博客_尺取法

(2条消息) 算法基础----尺取法(双指针)_jkaliang的博客-CSDN博客

尺取法比暴力枚举区间的效率高很多(特别是数据量大时,比如10^6),是一种高效枚举区间的方法,用于求取有一定限制的区间个数最短区间 

本题中通过左边界右移,右边界右移的方法,找到满足区间,并用ans(wer)保留最小区间

5,关于如何判断尺取法的区间包含了所有元素

我们用数组b保存a中不重复元素,得到不重复元素个数num

遍历时,设置游标 i ,游标右移过程中,代表区间的结束位置

得到num后,数组b使命结束,初始化数组b

每到达一页 i ,如果该页内容 a[i] 原来不在区间内,即b[a[i]] == 0

令b[a[i]]++, 表示区间内a[i]的个数为b[a[i]]个, 然后cnt++(cnt是count的意思)

-- --后面出队和包含所有数判断的操作,与第一题一样,不再赘述-- --

代码1

这是我Runtime Error的代码 

#include<iostream>
#include<cstdio> //scanf(), printf()
#include<cstring> //memset()
const int N = 1000100;
int a[N], b[N];
int main()
{
    int n, num = 0, cnt = 0;
    scanf("%d", &n);
    int ans = n;
    for(int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        if(b[a[i]] == 0) {
            num++;
            b[a[i]] = 1;
        } //得到不重复元素个数num
    }
    memset(b, 0, sizeof(b)); //初始化数组b
    for(int i = 0, j = 0; i < n; ++i) {
        if(b[a[i]] == 0) //a[i]原来不在区间内
            cnt += 1; //区间内不重复元素个数
        b[a[i]]++; //区间内a[i]个数
        while(cnt == num) { //区间包括所有内容,这里不用if
            if(ans > i - j + 1) ans = i - j + 1;
            b[a[j]]--;
            if(b[a[j]] == 0) cnt--;
            j++; //左边界右移, j++记得放最后!!!
        }
    }
    printf("%d", ans);
    return 0;
}

Runtime Error一般表示数组越界,由题目可知,每个数字最大为32位整型,这时让数组b一一对应就会越界,比如

2
0 173741824

这是大佬用了map后AC的代码👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

关于map C++硬货——map头文件【保姆级教学】_白凤倚剑归的博客-CSDN博客 

代码2 

#include<cstdio> //scanf(), printf()
#include<map>

int a[1000100];
std::map<int, int> b;
std::map<int, int>::iterator it;

int main()
{
    int n, num = 0, cnt = 0;
    scanf("%d", &n);
    int ans = n;
    for(int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        if(b[a[i]] == 0) {
            num++;
            b[a[i]] = 1;
        } //得到不重复元素个数num
    }
    for(it = b.begin(); it != b.end(); it++)
        it->second = 0; //初始化b
    for(int i = 0, j = 0; i < n; ++i) {
        if(b[a[i]] == 0) //a[i]原来不在区间内
            cnt += 1; //区间内不重复元素个数
        b[a[i]]++; //区间内a[i]个数
        while(cnt == num) { //区间包括所有内容,这里不用if
            if(ans > i - j + 1) ans = i - j + 1;
            b[a[j]]--;
            if(b[a[j]] == 0) cnt--;
            j++; //左边界右移, j++记得放最后!!!
        }
    }
    printf("%d", ans);
    return 0;
}

当然,还有一条路,离散化

(2条消息) C++算法——离散化_是挺秃然的齐齐哦的博客-CSDN博客_c++离散化

总结

学习了新的算法思想,尺取法(双指针)

补充了对scanf()和cin的理解

初次了解map离散化

巩固了队列快排

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

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

相关文章

一文讲透单点登录架构思想(SSO)

目录什么是单点登录&#xff1f;非单点登录架构单点登录架构什么是CAS单点登录SSO演进1.同域2.同父域3.跨域CASCAS术语CAS场景单点登录优缺点优点缺点什么是单点登录&#xff1f; 单点登录(SingleSignOn&#xff0c;SSO)&#xff0c;就是通过用户的一次性鉴别登录。当用户在身份…

【数据结构与算法理论知识点】 4、树和二叉树

4、树和二叉树 逻辑结构 4.1、树的定义和基本术语 树是n个结点的有限集 树的其他表示方式 基本术语 根——即根结点&#xff08;没有前驱&#xff09; 叶子——即终端结点&#xff08;没有后继&#xff09; 森林——指m棵不相交的树的集合&#xff08;例如删除根节点A后的…

Apache Solr 9.1-(二)集群模式运行

Apache Solr 9.1-&#xff08;二&#xff09;集群模式运行 Solr是一个基于Apache Lucene的搜索服务器&#xff0c;Apache Lucene是开源的、基于Java的信息检索库&#xff0c;Solr能为用户提供无论在任何时候都可以根据用户的查询请求返回结果&#xff0c;它被设计为一个强大的文…

synchronized锁升级

假如 synchronized 是「王」身边的「大总管」&#xff0c;那么 Thread 就像是他后宫的王妃。「王」每日只能选择一个王妃陪伴&#xff0c;王妃们会想方设法争宠获得陪伴权&#xff0c;大总管需要通过一定的手段让王「翻牌」一个「王妃」与王相伴。 今日听「码哥」胡言乱语解开…

1. Linux 磁盘管理(分区、格式化、挂载)

目录 1. Linux 内核版与发行版 2. Linux中磁盘的管理(分区、格式化、挂载) 2.1 磁盘定义、分类和命名 2.2 分区的定义和划分 2.3 磁盘格式化(高级/逻辑格式化) 2.4 挂载操作 1. Linux 内核版与发行版 内核版&#xff1a;Linus Torvalds最初组织很多人完成的Linux操作系统只…

Ubuntu20.04下安装显卡驱动

环境配置 系统: Ubuntu 20.04 CPU: i5 GPU:Geforce 960M Ubuntu安装显卡驱动 1、查看当前显卡安装情况 使用glxinfo查看 https://dri.freedesktop.org/wiki/glxinfo/ $ glxinfo Command glxinfo not found, but can be installed with: sudo apt install mesa-utils需要安…

postgresql FDW概念、用法与原理小结

最近突然遇到了一批使用fdw的场景&#xff0c;整理记录一把。 一、 强大的FDW FDW (foreign-data wrapper&#xff0c;外部数据包装器)&#xff0c;可以让我们在PG中使用SQL查询极为丰富的外部数据&#xff1a; 本实例和其他pg实例中的pg库主流关系型数据库&#xff1a;Oracle…

装饰模式(decorator-pattern)

装饰模式(decorator-pattern) 文章目录装饰模式(decorator-pattern)一、手抓饼点餐系统二、要求进阶三、装饰模式概要四、装饰模式的优劣及应用场景1. 优点2.缺点3.应用场景一、手抓饼点餐系统 请设计一个手抓饼点餐系统&#xff0c;支持加配菜&#xff0c;比如里脊、肉松、火…

C++ STL

目录 1.STL诞生 2.STL概念 3.STL六大主件 4.STL容器 算法 迭代器 5.容器算法迭代器初识&#xff0c;vector 5.1vector存放内置数据类型&#xff0c; 5.2vector存放自定义数据类型&#xff0c;解引用.访问&#xff0c;指针->访问&#xff0c;存放自定义数据类型指针。迭代器…

LeetCode(Array)1365. How Many Numbers Are Smaller Than the Current Number

1.问题 Given the array nums, for each nums[i] find out how many numbers in the array are smaller than it. That is, for each nums[i] you have to count the number of valid j’s such that j ! i and nums[j] < nums[i]. Return the answer in an array. Examp…

多目标建模总结

1. 概述 在推荐系统中&#xff0c;通常有多个业务目标需要同时优化&#xff0c;常见的指标包括点击率CTR、转化率CVR、 GMV、浏览深度和品类丰富度等。为了能平衡最终的多个目标&#xff0c;需要对多个目标建模&#xff0c;多目标建模的常用方法主要可以分为&#xff1a; 多模…

Linux常用命令——top命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) top 显示或管理执行中的程序 补充说明 top命令可以实时动态地查看系统的整体运行情况&#xff0c;是一个综合了多方信息监测系统性能和运行信息的实用工具。通过top命令所提供的互动式界面&#xff0c;用热键可…

C primer plus学习笔记 —— 13、存储类别、内存管理

文章目录存储类别定义、声明和初始化的区别作用域翻译单元和文件链接属性存储期存储类别多文件共享全局变量函数的存储类别存储类别的选择分配内存&#xff08;malloc、free&#xff09;malloc和calloc创建数组方式free的重要性举例存储类别 int a 1; int *p &a; int ra…

【Stm32野火】:野火STM32F103指南者开发板烧写官方示例程序LCD无法点亮?LCD示例程序无法使用?

项目场景&#xff1a; 大家好&#xff0c;最近在使用野火STM32F103指南者开发板的时候发现官方的示例程序LCD驱动代码居然无法直接驱动LCD点亮&#xff0c;这让我百思不得其解&#xff0c;以下就是我的踩坑填坑的过程&#xff0c;希望对大家有所帮助。 野火官方资料下载文档链接…

systemd介绍

systemd是一个 Linux 系统基础组件的集合&#xff0c;提供了一个系统和服务管理器&#xff0c;运行为 PID 1 并负责启动其它程序。功能包括&#xff1a;支持并行化任务&#xff1b;同时采用 socket 式与 D-Bus 总线式激活服务&#xff1b;按需启动守护进程&#xff08;daemon&a…

与Oracle不一样的union

与Oracle不一样的union一、引言二、实验探寻union2.1 再现DM8案例2.2 再现Oracle案例2.3 实验结论一、引言 前三日&#xff0c;同事call我聊发文查询优化排序问题&#xff0c;当时联想到union自身的特性&#xff08;合并去重&#xff0c;默认排序输出结果集&#xff09;&#…

(考研湖科大教书匠计算机网络)第一章概述-第五节2:计算机网络体系结构之OSI参考模型和TCPIP参考模型

文章目录一&#xff1a;OSI参考模型&#xff08;1&#xff09;应用层&#xff08;Application Layer&#xff09;&#xff08;2&#xff09;表示层&#xff08;Presentation Layer&#xff09;&#xff08;3&#xff09;会话层&#xff08;Session Layer&#xff09;&#xff0…

STC32G 单片机系列通用定时器的用法及编程

STC32G单片机与STC15系列单片机一样有T0~T4共5个通用定时器。其功能大致相同&#xff0c;与STC15系列单片机定时器不同的是STC32G单片机的定时器每个都多了一个8位预分频器&#xff0c;如下&#xff1a;这样定时器可作为一个24位定时器使用&#xff0c;做计数器使用与分频器就没…

【Flink】浅谈Flink背压问题(1)

概述 在多线程的情况下有一个典型的模&#xff0c;型生产者消费者模型&#xff0c;该模型主要由生产者、消费者和一个大小固定的队列组成。生产者向队列发送数据&#xff0c;消费者从队列中取出数据并处理。 针对上述模型&#xff0c;如果队列属于有限长度&#xff0c;当消费者…

UE5执行Python脚本插件

1.启用UE5的Python脚本编辑器&#xff1a; 在Edit里面找到Plugins&#xff0c;然后打开插件管理器&#xff0c;搜索Python,找到 Python Editor Script Plugin并启用它。该插件也可能会自动启用&#xff08;至少我的UE5是这样的&#xff09;&#xff0c;如果已经自动启用&#…