[蓝桥杯] 枚举、模拟和排列问题

news2024/9/21 12:32:40

 

文章目录

一、连号区间数 

1、1 题目描述

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

二、递增三元组

2、1 题目描述

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

三、错误票据

3、1 题目描述

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

四、回文日期

4、1 题目描述

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

五、归并排序


标题:蓝桥杯——枚举、模拟和排列习题训练

作者:@Ggggggtm

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

一、连号区间数 

1、1 题目描述

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

题目难度:简单

题目描述:

小明这些天一直在思考这样一个奇怪而有趣的问题:

在 1∼N 的某个排列中有多少个连号区间呢?

这里所说的连号区间的定义是:

如果区间 [L,R] 里的所有元素(即此排列的第 L 个到第 R 个元素)递增排序后能得到一个长度为 R−L+1 的“连续”数列,则称这个区间连号区间。

当 N 很小的时候,小明可以很快地算出答案,但是当 N 变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入格式:

第一行是一个正整数 N,表示排列的规模。

第二行是 N 个不同的数字 Pi,表示这 N 个数字的某一排列。

输出格式:

输出一个整数,表示不同连号区间的数目。

数据范围:

1≤N≤10000,
1≤Pi≤N

输入样例1:

4
3 2 4 1

输出样例1:

7

输入样例2:

5
3 4 2 5 1

输出样例2:

9

样例解释:

第一个用例中,有 77 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4][1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4]
第二个用例中,有 99 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[1,5],[2,2],[3,3],[4,4],[5,5]

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

  首先,我们仔细阅读题目。题中提到了1∼N 的某个排列,注意是排列,所以是1∼N 中没有重复的数据,且所有数据都会出现一次。题目大概意思是给我们一组数据,是乱序的。然后我们需要在这组数据中任选一段连续区间,看是否能组成“连续”数列。我们第一想到的是两层for循环枚举区间,在对区间排序,判断是否为“连续”数列。这样时间复杂度显然是不能通过题中所有案例的。我们仔细观察,区间数值不会重复,那么区间的最大值减去区间的最小值等于区间下标相减。这样大大提高了效率,我们结合代码一起理解一下。

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

using namespace std;

int n;

const int N =10010;
const int MAX=-1e8,MIN=1e8;

int a[N];

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    
    int res=0;
    for(int i=0;i<n;i++)
    {
        int maxc=MAX,minc=MIN;
        for(int j=i;j<n;j++)
        {
            maxc=max(maxc,a[j]);
            minc=min(minc,a[j]);
            if(maxc-minc==j-i)
                res++;
        }
    }
    
    cout<<res<<endl;
    return 0;
}

二、递增三元组

2、1 题目描述

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

题目难度:简单

题目描述:

给定三个整数数组

A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],

请你统计有多少个三元组 (i,j,k) 满足:

  1. 1≤i,j,k≤N
  2. Ai<Bj<Ck

输入格式:

第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,…AN。

第三行包含 N 个整数 B1,B2,…BN。

第四行包含 N 个整数 C1,C2,…CN。

输出格式

一个整数表示答案。

数据范围

1≤N≤1e5,
0≤Ai,Bi,Ci≤1e5。

输入样例:

3
1 1 1
2 2 2
3 3 3

输出样例:

27

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

  这道题的暴力枚举的方法很容易想到,直接三层循环,进行比较。但是时间复杂度为O(N^3),是不能全部通过测试用例的。我们仔细分析题目。题目要求:Ai<Bj<Ck。这里A和C都需要与B进行比较,且A和C不产生直接联系。所以我们只需要枚举Bj,然后找所有Ai比Bj小的数,所有Ck比Bj大的数即可。我们这里利用了前缀和来找值,优化了时间复杂度。最后将得到的两个数据直接相乘即为答案,我们看代码。

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

using namespace std;

const int N=1e5+10;

typedef long long LL;

int n;

int a[N],b[N],c[N];

int as[N],cs[N];  //分别表示的是比b[i]小的个数和比b[i]大的个数
int cnt[N],s[N];

int main()
{
    cin>>n;
    
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        a[i]++;
    }
    
    for(int i=0;i<n;i++)
    {
        scanf("%d",&b[i]);
        b[i]++;
    }
    
    for(int i=0;i<n;i++)
    {
        scanf("%d",&c[i]);
        c[i]++;
    }
    
    //求as[]
    for(int i=0;i<n;i++)
        cnt[a[i]]++;
    for(int i=1;i<N;i++)
        s[i]=s[i-1]+cnt[i];
    for(int i=0;i<n;i++)
        as[i]=s[b[i]-1];
    
    memset(cnt,0,sizeof(cnt));
    memset(s,0,sizeof(s));
    //求cs[]
    for(int i=0;i<n;i++)
        cnt[c[i]]++;
    for(int i=1;i<N;i++)
        s[i]=s[i-1]+cnt[i];
    for(int i=0;i<n;i++)
        cs[i]=s[N-1]-s[b[i]];
    
    LL res=0;
    for(int i=0;i<n;i++)
        res+=(LL)as[i]*cs[i];
    
    cout<<res<<endl;
    return 0;
}

三、错误票据

3、1 题目描述

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

题目难度:简单

题目描述:

某涉密单位下发了某种票据,并要在年终全部收回。

每张票据有唯一的ID号。

全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。

因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。

你的任务是通过编程,找出断号的ID和重号的ID。

假设断号不可能发生在最大和最小号。

输入格式:

第一行包含整数 N,表示后面共有 N 行数据。

接下来 N 行,每行包含空格分开的若干个(不大于100个)正整数(不大于100000),每个整数代表一个ID号。

输出格式:

要求程序输出1行,含两个整数 m,n,用空格分隔。

其中,m表示断号ID,n表示重号ID。

数据范围:

1≤N≤100,

输入样例:

2
5 6 8 11 9 
10 12 9

输出样例:

7 9

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

  我们先对所有数据进行排序。然后我们会发现连号和中间缺少一个都是有特点的。连号是连续两个相等,中间缺少一个的特点是后一个减去前面一个的值为2。本题的难点是在读入。每行的个数不相同,且有多行,这就给我们的读入造成了很大的困难。我们在这里可以用getline对每行进行读入,最后再用户sscanf进行格式化输入。这样我们就可以解决问了。注意,在使用getline时,我们要想清楚现在的输入缓冲区是否还有 '\n'、空格之类的。我们结合代码理解一下。 

#include<iostream>
#include<algorithm>
#include<sstream>
#include<cstring>

using namespace std;

const int N=10010;

int n;
int a[N];

int main()
{
    int cnt;
    cin>>cnt;
    string line;
    
    getline(cin,line);
    
    while(cnt--)
    {
        getline(cin,line);
        stringstream ssin(line);
        
        while (ssin >> a[n]) n ++ ;
    }
    
    sort(a,a+n);
    
    int res1,res2;
    for(int i=1;i<n;i++)
        if(a[i]==a[i-1])
            res1=a[i];
        else if(a[i]==a[i-1]+2)
            res2=a[i]-1;
    cout<<res2<<' '<<res1<<endl;
    return 0;
}

四、回文日期

4、1 题目描述

题目来源:NOIP2016普及组

题目难度:简单

题目描述:

  在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。

  牛牛习惯用 8 位数字表示一个日期,其中,前 4 位代表年份,接下来 2 位代表月份,最后 2 位代表日期。

  显然:一个日期只有一种表示方法,而两个不同的日期的表示方法不会相同。

  牛牛认为,一个日期是回文的,当且仅当表示这个日期的 88 位数字是回文的。

  现在,牛牛想知道:在他指定的两个日期之间(包含这两个日期本身),有多少个真实存在的日期是回文的。

  一个 8 位数字是回文的,当且仅当对于所有的 i(1≤i≤8) 从左向右数的第 i 个数字和第 9−i 个数字(即从右向左数的第 i 个数字)是相同的。

例如:

  • 对于 2016 年 11 月 19 日,用 8 位数字 20161119 表示,它不是回文的。
  • 对于 2010 年 1 月 22日,用8 位数字 20100102 表示,它是回文的。
  • 对于 2010年 10 月 2 日,用 8 位数字 20101002 表示,它不是回文的。

输入格式:

  输入包括两行,每行包括一个 8 位数字。

  第一行表示牛牛指定的起始日期 date1,第二行表示牛牛指定的终止日期 date2。保证date1 和 date2 都是真实存在的日期,且年份部分一定为 4 位数字,且首位数字不为 00。

保证 date1 一定不晚于 date2。

输出格式:

  输出共一行,包含一个整数,表示在 date1 和 date2 之间,有多少个日期是回文的。

输入样例:

20110101
20111231

输出样例:

1

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

   该题要求我们求一个年份区间的回文日期,好像很麻烦。我们先想想,题目中的日期统一为8位数字。前四位为年,后四位分别为月和天。我们不如直接枚举年份,从1000枚举到10000,然后通过年份制造出一个回文串。再去判断该回文串是否为合法日期。这样似乎做起来很简单。我们来看代码。

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

using namespace std;

int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

bool check_date(int date)
{
    int year=date/10000;
    int month=date%10000/100;
    int day=date%100;
    
    if(month==0 || month>12)
        return false;
    
    if(day==0 || month != 2 && day>days[month])
        return false;
    
    if (month == 2)
    {
        int leap = year % 100 && year % 4 == 0 || year % 400 == 0;
        if (day > 28 + leap) return false;
    }
    
    return true;
}
int main()
{
    int date,date1,date2;
    
    int res=0;
    cin>>date1>>date2;
    for(int i=1000;i<10000;i++)
    {
        date=i;
        int x=i;
        for(int i=0;i<4;i++)
        {
            date=date*10+x%10;
            x/=10;
        }
        
        if(date1<=date && date<=date2 && check_date(date))
            res++;
    }
    
    cout<<res<<endl;
    return 0;
}

五、归并排序

  归并排序在蓝桥杯中也是有考到的,所以我们也要重点掌握。此篇文章:重点算法排序之快速排序、归并排序(上篇) 对归并排序做出了详解,可以参考学习。

  今天的学习就到这里,希望以上的例题和讲解希望对你有所帮助,感谢阅读ovo~ 

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

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

相关文章

windows和linux出现timewait过多的解决方法

一、timewait出现在客户端还是服务端以及什么情况下出现 我是做性能测试的。在压测过程中遇到了timewait过多的情况&#xff0c;下面来看一下timewait产生的原因及解决办法&#xff0c;我自己在服务器起了一个很简单的springboot应用来验证自己的猜想及解决办法。 说到产生原…

基于docker部署prometheus

1、prometheus架构 Prometheus Server: 收集指标和存储时间序列数据&#xff0c;并提供查询接口 ClientLibrary:客户端库 Push Gateway: 短期存储指标数据。主要用于临时性的任务 Exporters:采集已有的第三方服务监控指标并暴露 metrics Alertmanager:告警 Web UI :简单的…

VS插件CodeRush全新发布v22.2.4——改进对VS 17.5的支持

CodeRush是一个强大的Visual Studio .NET 插件&#xff0c;它利用整合技术&#xff0c;通过促进开发者和团队效率来提升开发者体验。CodeRush能帮助你以极高的效率创建和维护源代码。Consume-first 申明&#xff0c;强大的模板&#xff0c;智能的选择工具&#xff0c;智能代码分…

【C++升级之路】第九篇:vector

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【C学习与应用】 ✒️✒️本篇内容&#xff1a;vector的基本概念、vector的使用&#xff08;构造&#xff0c;迭代器&#xff0c;空间增长&#xff0c;增删…

小樽C++ 单章③ 一维数组

目录 一、一维数组认识与使用 1.4 数组的输入与输出 1.5 最大值与最小值的求解 二、一维数组的操作用法 2.1 数组的插入与删除 2.2 数组某个值的查找 2.3多个数组的合并 2.4多个数组的有序合并 三、一维数组的应用 3.1 斐波那契数列 3.2 淘淘摘苹果 3.3 翻纸牌游戏…

RTOS中互斥量的原理以及应用

互斥量的原理 RTOS中的互斥量是一种同步机制&#xff0c;用于保护共享资源&#xff0c;防止多个任务同时访问该资源&#xff0c;从而避免数据竞争和不一致性。 互斥量的原理是通过对共享资源进行加锁和解锁操作来实现的。 在RTOS中&#xff0c;互斥量通常是一个数据结构&…

为什么说要慎用BeanUtils,因为性能真的拉跨

1 背景之前在专栏中讲过“不推荐使用属性拷贝工具”&#xff0c;推荐直接定义转换类和方法使用 IDEA 插件自动填充 get / set 函数。不推荐的主要理由是&#xff1a;有些属性拷贝工具性能有点差有些属性拷贝工具有“BUG”使用属性拷贝工具容易存在一些隐患&#xff08;后面例子…

九龙证券|磷酸亚铁锂是什么?磷酸亚铁锂的特点和性能介绍

磷酸亚铁锂是一种新式锂离子电池电极资料&#xff0c;化学式&#xff1a;LiFePO4&#xff0c;磷酸亚铁锂为近来新开发的锂离子电池电极资料&#xff0c;首要用于动力锂离子电池&#xff0c;作为正极活性物质运用&#xff0c;人们习气也称其为磷酸铁锂。 磷酸亚铁锂的特色和功能…

【计算机网络】随机访问介质访问控制中的ALOHA协议、CSMA协议、CSMA/CD协议和CSMA/CA协议

二、随机访问介质访问控制 信道上的所有用户可随机发送信息 1. 简单ALOHA协议 解决信息发送时的冲突问题。其特点是不监听信道&#xff0c;不按时间槽发送&#xff0c;随机重发。 思想&#xff1a;在超时后&#xff0c;等随机一段时间后再重传 2. 时隙ALOHA协议 时隙ALOH…

送给她最最浪漫的表白(Python代码实现)

目录I 最美的浪漫 II 昨日浪漫的表白III 关于“美”的哲思 IV Python代码实现 I 最美的浪漫 II 昨日浪漫的表白 她问:有一个问题&#xff0c;我只问一遍&#xff0c;为什么是我?我微微一笑答道:笞案很长&#xff0c;我要用一生来回答。我&#xff1a;图书馆旁边的星空真美&…

Linux面试总结

一.常用命令1.目录切换cd / 切换到根目录cd ../ 切换到上级目录cd ~ 切换到home目录2.查看目录ls 列出当前目录下所有的文件ls [路径]ls / 查看根目录 ls -l 相当于 ll 最常用的命令,用了表的方式列出当前目录的内容3.查看当前目录pwd-4.创建一组空文件touch5.显示文件内容cat6…

Maven打包操作

对于企业级项目&#xff0c;无论是进行本地测试&#xff0c;还是测试环境测试以及最终的项目上线&#xff0c;都会涉及项目的打包操作。对于每个环境下的项目打包&#xff0c;对应的项目所需要的配置资源都会有所区别&#xff0c;实现打包的方式有很多种&#xff0c;可以通过an…

【Linux】进程理解与学习(Ⅰ)

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统进程概念什么是进程&#xff1f;进程是什么&#xff1f;我们打开任务管理器可以看到有…

Flex弹性布局一文通【最全Flex教学】

文章目录一.Flex布局1.1 传统布局和flex布局1.1.1 传统布局1.1.2 flex弹性布局1.2 flex初步体验1.3 布局原理二.常见Flex属性2.1 常见父项属性2.2 flex-direction主轴的方向2.3 justify-content设置主轴上的子元素排列方式2.4 设置子元素是否flex-wrap换行2.5 align-itmes设置侧…

数列的极限

数列的极限的定义&#xff1a; 当正多边形的边数越来越多时&#xff0c;正多边形的面积越来越接近于圆的面积。 这个过程就叫做极限。 数列的形式&#xff1a; 数列的每一个下标对应一个数列元素值。 认识数列 这就是4个数列的表现形式。 当数列的下标无限增长时&#xff0c…

记录--uni-app中安卓包检查更新、新版本下载、下载进度条显示功能实现

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 需求描述 如果想要做一个app的话&#xff0c;可以有很多种选择方案&#xff0c;uni-app是其中的一个性价比高一些(坑多一些)的方案。本文记录一下&#xff0c;uni-app打安卓包以后&#xff0c;需要检查…

【操作系统】如何避免预读失效和缓存污染的问题?

【操作系统】如何避免预读失效和缓存污染的问题&#xff1f; 文章目录【操作系统】如何避免预读失效和缓存污染的问题&#xff1f;Linux 和 MySQL 的缓存Linux 操作系统的缓存MySQL 的缓存传统 LRU 是如何管理内存数据的&#xff1f;预读失效&#xff0c;怎么办&#xff1f;什么…

bash if 判断及特殊字符

bash if 判断 1)字符串判断 str1 str2     当两个串有相同内容、长度时为真 str1 ! str2     当串str1和str2不等时为真 -n str1       当串的长度大于0时为真(串非空) -z str1       当串的长度为0时为真(空串) str1        当串str1为非…

华为OD机试题,用 Java 解【众数和中位数】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…

Spark DPP

Spark DPP分区剪裁动态分区剪裁DPP (Dynamic Partition Pruning&#xff0c;动态分区剪裁) : 过滤维度表后&#xff0c;能削减事实表的数据扫描量&#xff0c;提升关联计算的执行性能 分区剪裁 需求 &#xff1a;统计所有头部用户贡献的营业额&#xff0c;并按照营业额倒序排…