蓝桥杯 第一场算法双周赛题解(前五题)

这篇具有很好参考价值的文章主要介绍了蓝桥杯 第一场算法双周赛题解(前五题)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目链接在此😁:第 1 场算法双周赛 - 蓝桥云课
为什么只有前5道题的题解呢?(懂的都懂~🤐)

第一题 三带一

考察:简单逻辑判断

问题描述

小蓝和小桥玩斗地主,小蓝只剩四张牌了,他想知道是否是“三带一”牌型。
所胃三带一”牌型,即四张手牌中,有三张牌一样,另外一张不与其他牌相同,换种说法,四张手牌经过重新排列后,可以组成 AAAB型

输入格式

第一行输入一个整数T,代表斗地主的轮数。
接下来T行,每行输入一个长度为 4的字符串,代表小蓝的手牌。
字符{'A’,’2’,‘3’,’4’,’5’,’6’,’7’,’8’,’9,’X’,’J’,’Q’,’K’}对应代表牌面{A,2,3,4,5,6,7,8,9,10,J,Q,K}。
牌面中不包含大小王。

输出格式

输出行,每行一个字符串,如果当前牌是“三带一”牌型,输出 Yes,否则输出 No。

样例输入

AAAA
33X3
JQKX
6566
KKKQ

样例输出

No
Yes
No
Yes

说明

“四炸”牌型不属于“三带一”牌型。

评测数据范围

数据范围: 1 ≤ T ≤ 50 1 \leq T \leq 50 1T50

字符中只包含:{A,2,3,4,5,6,7,8,9,X,J,Q,K}。

解题思路

第一题很简单,就是一个基本的逻辑判断,小细节就是对字符串排序可以减少判断量

代码

#include <bits/stdc++.h>
using namespace std;

int t;
string s;
signed main() {
    cin >> t;
    while (t--) {
        cin >> s;
        sort(s.begin(), s.end()); // 使其有序
        if (s[0] != s[3] && s[1] == s[2] && (s[0] == s[1] || s[2] == s[3])) cout << "Yes" << endl; // 说明是三带一
        else cout << "No" << endl;
    }    
    return 0;
}

第二题 数树数

考察:二叉树

问题描述

小蓝最近学了二又树,他想到了一个问题。
给定一个层数为n的满二叉树,每个点编号规则如下:

蓝桥杯 第一场算法双周赛题解(前五题),蓝桥杯,数据结构与算法,蓝桥杯,c++,数据结构,算法

具体来说,二叉树从上向下数第p 层,从左往右编号分别为: 1 , 2 , 3 , 4... 2 p − 1 1,2,3,4...2^{p-1} 1,2,3,4...2p1
小蓝给你一条从根节点开始的路径,他想知道到达的节点编号是多少。
例如: 路径是right - left,那么到达的节点是1-2-3,最后到了三号点,如下图所示。

蓝桥杯 第一场算法双周赛题解(前五题),蓝桥杯,数据结构与算法,蓝桥杯,c++,数据结构,算法

输入格式

第一行输入两个整数n,q,n 表示完全二树的层数, q代表询问的路径数量。
接下来q 行,每行一个字符串 S,S 只包含字符{‘L’, ’R’},’L’ 代表向左,’R’ 代表向右。

输出格式

输出q行,每行输出一个整数,代表最后到的节点编号。

样例输入

3 6
R
L
LL
LR
RL
RR

样例输出

2
1
1
2
3
4

说明

2 ≤ n ≤ 20 , 1 ≤ q ≤ 1 0 3 , 1 ≤ ∣ S ∣ ≤ n 2\leq n \leq 20,1 \leq q \leq 10^3,1 \leq |S| \leq n 2n20,1q103,1Sn
完全二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
也就是说如果一个二叉树的层数为 k k k,且节点总数是 2 k − 1 2^k-1 2k1,则它就是满二又树。

解题思路

考察的是二叉树的性质
顺序遍历路径S,用一个变量记录到达的节点的id。节点id的编排规则:

蓝桥杯 第一场算法双周赛题解(前五题),蓝桥杯,数据结构与算法,蓝桥杯,c++,数据结构,算法
再用id的值来计算目前所在的行数和列数。
如何用id来计算目前处于第几行的第几个节点呢?(这里用x代表id)
行数 = ⌊ l o g 2 x ⌋ + 1        ( ⌊ x ⌋ 表示对 x 向下取整 )   列数 = x − 2 行数 + 1 行数 = \lfloor log_2x \rfloor+1~~~~~~(\lfloor x \rfloor表示对x向下取整)\\ ~\\ 列数 = x - 2^{行数} + 1 行数=log2x+1      (⌊x表示对x向下取整) 列数=x2行数+1
~请读者自行证明😁

代码

#include <bits/stdc++.h>
using namespace std;

int n, q;
string s;
signed main() {
    cin >> n >> q;
    while (q--) {
        cin >> s;
        int id = 1;
        for (char& i : s) { // 遍历字符串
            if (i == 'L') res *= 2; // 向左子节点走 -> id乘以2
            else res = res * 2 + 1; // 向右子节点走 -> id乘以2再加一
        }
        cout << res - (1 << (int)log2(res)) + 1 << endl; // 利用公式输出结果
    }
    return 0;
}

第三题 分组

考察:二分答案

问题描述

蓝桥小学要进行弹弹球游戏,二年级一班总共有 n 个同学,要求分成 k 个队伍,由于弹弹球游戏要求队员
的身高差不能太大,小蓝是班长,他对这个事情正在发愁,他想问你,如何最小化每个组之间的身高极差。
具体的,假设分成了 k 个组,第 i 组最高的人身高是 H x i H_{x_i} Hxi,最矮的是 H n i H_{n_i} Hni,你被要求最小化表达式:
m a x ( H t i − H n i ) ,    1 ≤ i ≤ k max(H_{t_i}- H_{n_i}),~~1\leq i \leq k max(HtiHni),  1ik。直白来说,你需要将 n 个元素分出 k 组,使得最大的极差尽可能小。你需要输出这
个最小化化后的值。

输入格式

第一行输入两个整数n, k。
第二行输入n 个整数: h 1 , h 2 , h 3 . . . h n h_1,h_2,h_3...h_n h1,h2,h3...hn,分别代表 n 个人的身高

输出格式

输出一个整数,代表最小值。

样例输入

5 3
8 4 3 6 9

样例输出

1

说明

样例分组情况:{3, 4}, {6}, {8, 9}。

评测数据规模

数据范围: 1 ≤ k ≤ n ≤ 1 0 5 , 1 ≤ h i ≤ 1 0 9 1\leq k\leq n\leq 10^5,1\leq h_i\leq 10^9 1kn105,1hi109

解题思路

二分答案其实就是二分+贪心
(不知道为什么出题人总是爱考二分答案~,这种题都有一个特征:要么就是最小值最大化,要么就是最大值最小化,符合某种单调性)
首先,每一个分组都是身高尽可能接近的同学,可以证明:每一个分组都是排好序后的连续的几位~(因为如果不是这样,每一组的最大身高差只会增,不会减,最多保持不变)
然后就好说了,先排序,排完序后二分最大身高值,双指针遍历数组(对其分组),如果超过了最大值,就分组加一,如果分组超过了k,说明不行。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;
int n, k, h[N];
bool check(int x) { // 经典check函数(懂的都懂)
    int c = 1; // 分组数
    for (int l = 0, r = 1; r < n; r++) { // 双指针
        if (h[r] - h[l] > x) { // 分组结果是[l, r)
            c++;
            l = r;
            if (c > k) return false; // 需要的分组数大于k了,不满足条件
        }
    }
    return true; // 满足
}
signed main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) cin >> h[i];
    sort(h, h + n); // 排序
    int l = 0, r = 1e9; // 二分
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1; // 注意是mid + 1,不然会死循环
    }
    cout << l; // 结果
    return 0;
}

第四题 健身

考察:完全背包DP

问题描述

小蓝要去健身,他可以在接下来的 1 ~ n 天中选择一些日子去健身
他有 m 个健身计划,对于第 i 个健身计划,需要连续的 2 k 2^k 2k 天,如果成功完成,可以获得健身增益 s i s_i si,如果中断,得不到任何增益。
同一个健身计划可以多次完成,也能多次获得健身增益,但是同一天不能同时进行两个或两个以上的健身计划。
但是他的日程表中有 q 天有其他安排,不能去健身,问如何安排健身计划,可以使得 n 天的健身增益和最大。

输入格式

第一行输入三个整数n,m,q
第二行输入q个整数, t 1 , t 2 , t 3 . . . t q t_1,t_2,t_3...t_q t1,t2,t3...tq,代表有其他安排的日期
接下来 m 行,每行输入两个整数 k i , s i k_i,s_i ki,si。代表该训练计划需要 2 k i 2^{k_i} 2ki天,完成后可以获得 s i s_i si的健身增益

输出格式

一个整数,代表最大的健身增益和。

样例输入

10 3 3
1 4 9
0 3
1 7
2 20

样例输出

30

说明

在样例中2 - 3天进行计划2,5 - 8天进行计划3,10~10天进行计划1。

评测数据范围

1 ≤ q ≤ n ≤ 2 × 1 0 5 , 1 ≤ m ≤ 50 , 1 ≤ s i ≤ 1 0 9 , 0 ≤ g ≤ 20 , 1 ≤ t 1 < t 2 < . . . < t g ≤ n 1\leq q\leq n\leq 2\times10^5,1\leq m \leq 50,1\leq s_i\leq 10^9,0\leq g\leq 20,1\leq t_1 < t_2 < ... < t_g \leq n 1qn2×1051m501si1090g201t1<t2<...<tgn

解题思路

首先,根据题意,我们不难发现必须在有安排的日子的空隙时间来健身,而在这段空隙时间,我们选择健身项目来健身,对于每一个项目,有时间 2 k i 2^{k_i} 2ki和收益 s i s_i si
聪明的小伙伴可能已经发现,这就是一个背包dp问题
由于健身计划可以重复多次,所以是完全背包问题,然后用滚动数组来优化空间。
由于要多次dp计算,可以用一个额外数组记忆化来保存

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 2e5 + 5, M = 55;
ll n, m, q, t[N], k[M], s[M];
ll dp[N], mem[N]; // 记忆化数组
ll calc(int x) { // dp
    memset(dp, 0, n << 2);
    for (int i = 0; i < m; i++)
        for (int j = k[i]; j <= x; j++) { // 从小到大就是完全背包,从大到小是01背包~
            if (dp[j - k[i]] + s[i] > dp[j])
                dp[j] = dp[j - k[i]] + s[i];
        }
    return dp[x];
}
signed main() {
    cin >> n >> m >> q;
    for (int i = 1; i <= q; i++) cin >> t[i];
    for (int i = 0; i < m; i++) {
        cin >> k[i] >> s[i];
        k[i] = 1 << k[i]; // 需要花费的时间
    }
    t[q + 1] = n + 1; // 不遗漏最后的空隙时间
    ll res = 0;
    for (int i = 1; i <= q + 1; i++)
        if (t[i] - t[i - 1] - 1 >= 1) { // 有空隙时间
            if (!mem[t[i] - t[i - 1] - 1])
            	mem[t[i] - t[i - 1] - 1] = calc(t[i] - t[i - 1] - 1); // 记忆化
            res += mem[t[i] - t[i - 1] - 1];
        }
    cout << res;
    return 0;
}

Very important!!!

一定要开long long!一定要开long long!一定要开long long!

第五题 契合匹配

考察:KMP

问题描述

小蓝有很多齿轮,每个齿轮的凸起和凹陷分别用一个字符表示,一个字符串表示一个齿轮
蓝桥杯 第一场算法双周赛题解(前五题),蓝桥杯,数据结构与算法,蓝桥杯,c++,数据结构,算法

如果两个齿轮的对应位分别是同一个字母的大小写,我们称这两个齿轮是契合的
例: AbCDeFgh 和 aBcdEfGH 就是契合的,但是 abc 和 aBC 不是契合的
这天,小蓝的弟弟小桥从抽屉里拿来了两个齿轮,小蓝想知道,这俩个齿轮是不是契合的。
特别需要注意的是,齿轮是环形的,所以是可以旋转的(顺时针和逆时针均可),如果是契合的,小蓝还想
让你告诉他,最少将第一个齿轮旋转多少位,两个齿轮可以完全契合在一起
例如: AbbCd 与BcDaB,在将第一个齿轮逆时针旋转两位后,变成 bCdAb ,两个齿轮就完全契合在一起了

输入格式

第一行输入一个正整数n,代表两个齿轮的长度
第二行输入一个长度为的字符串S,代表第一个齿轮
第三行输入一个长度为n的字符串T,代表第二个齿轮

输出格式

第一行输出一个字符串: Yes 或者 No 。代表两个齿轮是否契合
如果可以契合,第二行输出一个整数,代表需要旋转的位数。
如果不可以契合,不用多余输出。

样例输入

5
AbbCd
BcDaB

样例输出

Yes
2

评测数据范围

数据范围: 1 ≤ n ≤ 1 0 6 1\leq n\leq 10^6 1n106
保证字符串只包含大小写字母

解题思路

这题就是判断T是不是S的循环同构串,没什么其它好说的,就是很明显的KMP,直接把模板拿过来用就行了~😁
要注意顺时针和逆时针旋转都可以,所以从两种转法中取最小值

代码

#include <bits/stdc++.h>
using namespace std;

int n;
string s, t;
int Next[1000010]; // Next[i]:以第i个字符结尾的前缀字符串的最大前后缀字符串长
void getFail(string& p) {
    int plen = p.length();
    Next[1] = Next[0] = 0;
    for (int i = 1; i < plen; i++) {
        int j = Next[i];
        while (j && p[i] != p[j]) j = Next[j];
        Next[i + 1] = p[i] == p[j] ? j + 1 : 0;
    }
}
int kmp(string& s, string& p) {
    int slen = s.length(), plen = p.length();
    int j = 0;
    for (int i = 0; i < slen; i++) {
        while (j && abs(s[i] - p[j]) != 32) j = Next[j]; // 注意匹配的条件
        if (abs(s[i] - p[j]) == 32) j++; // 这里也是
        if (j == plen) return i - j + 1;
    }
    return -1;
}
signed main() {
    cin >> n >> s >> t;
    s += s; // 在尾部再加上一个s后,s的循环同构串就会出现在新的s中
    getFail(t);
    int res = kmp(s, t);
    if (res != -1) cout << "Yes" << endl << min(res, n - res); // 注意顺时针和逆时针旋转都可以
    else cout << "No";
    return 0;
}

比赛总结

蓝桥杯 第一场算法双周赛题解(前五题),蓝桥杯,数据结构与算法,蓝桥杯,c++,数据结构,算法

前两道题还算比较顺利,但是到了后面疯狂出错😭,害,都习惯了
第三题是check函数写错了,两次都没检测出来
第四题刚开始超时了几次,因为忘了完全背包怎么写了,用多重背包的思路做的,后面因为没开long long,又错了好几次,有一个地方没开long long都不行,唉~,C++永远的坑(老是检查不出来)
第五题是因为没注意正着转和反着转都行。。。错了两次
排名就这样了,我太菜了😭
有什么问题欢迎在评论区留言~文章来源地址https://www.toymoban.com/news/detail-717020.html

到了这里,关于蓝桥杯 第一场算法双周赛题解(前五题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 蓝桥杯双周赛算法心得——通关(哈希+小根堆)

    大家好,我是晴天学长,这是很重要的贪心思维题,哈希的存法和小根堆的表示很重要。💪💪💪 1) .通关 2) .算法思路 通关 用hash(int[])存点的子节点并按输入顺序存关卡的号码(输入顺序就是) 列如:key:父节点 难度 经验 关卡 优先队列存难度和节点 1.接受数据和初始

    2024年02月08日
    浏览(36)
  • 蓝桥杯双周赛算法心得——铺地板(质因数)

    大家好,我是晴天学长,这是第二周的蓝桥杯的双周赛,题可出的又好又灵活啊!真不错!💪💪💪 1) .铺地板 2) .算法思路 1.导入java.util包中的Scanner类,以从用户那里读取输入。 2.main方法是程序的入口点。 3.创建一个Scanner对象,用于从标准输入读取输入。 4.从用户那里读取

    2024年02月08日
    浏览(43)
  • 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛[第一场]程序设计题以及详细题解

      今年的第一场比赛绝对np,官方将串口直接省掉了,将其替换成很多小功能,如:切换计时、频率均匀变化、锁机制等等,总的来说本届赛题的难度提升了不少。   本届试题需要用到的功能模块有 LCD 、 LED 、 按键 、 定时器输入捕获 、 定时器PWM输出 、 ADC获取 ,虽然这

    2023年04月17日
    浏览(83)
  • 第 122 场 LeetCode 双周赛题解

    A 将数组分成最小总代价的子数组 I 枚举:枚举后两个子数组的起始下标 B 判断一个数组是否可以变为有序 模拟:模拟冒泡排序的过程,若相邻元素大小关系需要交换位置,但其二进制下数位为 1 的数目不同,则返回false,若完成排序返回true C 通过操作使数组长度最小 脑筋急

    2024年01月22日
    浏览(42)
  • 【蓝桥杯】蓝桥杯双周赛第二场ABCD题

    知识点:下一届是第几届蓝桥杯……         新一届蓝桥杯大赛即将在2024年拉开序!         作为大一新生的小蓝,在听说了这场盛大的比赛后,对其充满了期待与热情。但作为初次参赛的新手,他对蓝桥杯的相关赛制和历史并不了解。于是,他决定寻求上届蓝桥杯总冠

    2024年02月08日
    浏览(42)
  • 【蓝桥杯】蓝桥杯双周赛第二场E题

    知识点:树的直径          过年了。         蓝桥村可以抽象为n个节点,n - 1条边的一棵树,每条边有边权长度wi。         小蓝可以选择任意一个点作为起点,然后选择一条路径,可以访问每一个节点最少一次。他想知道最短的路径长度是多少。 输入格式         第一

    2024年02月06日
    浏览(46)
  • 《蓝桥杯真题》:2021单片机省赛第一场(第十二 / 12届第一场)(另一种代码风格)

    注意: 代码实现方面 : ①注意控制温度参数temp_para范围 ②DAC输出时,注意写入的数字IIC_SendByte(temp)中temp范围在 0~255 ; 源文件修改方面 : ①官方给的iic.h中使用的时C51的头文件\\\"reg52.h\\\",我们需要 修改为 对应的15系列 头文件\\\"STC15F2K60S2.h\\\" ,这样才可以使用其中的一些特殊位寄

    2023年04月08日
    浏览(50)
  • 零基础!无门槛!高额现金奖励!优秀的大学生都在打这场算法双周赛

       spacespace     大家好,我是执梗。在蓝桥杯中获得过十三届 Java B 组国一以及十四届 C++ B 组的国一。今天主要为大家带来一个好消息,蓝桥杯将为各位喜爱算法的小伙伴带来全新的算法双周赛。如果你热爱算法竞赛,或者准备参加十五届的蓝桥杯比赛,那么一定不要错过

    2024年02月08日
    浏览(62)
  • 第十二届蓝桥杯嵌入式省赛第一场真题(基于HAL库的巨简代码+超级详解)

    相关说明: 开发板:CT117E-M4(STM32G431RBT6) 开发环境: CubeMX+Keil5 涉及题目:第十二届蓝桥杯嵌入式省赛第一场真题 技巧:字符串比较 、字符串数组转移提取、for和return搭配使用、goto语句、利用%c和%s打印 CubeMX配置、主要函数代码及说明: 1.使能外部高速时钟: 2.配置时钟树:

    2023年04月11日
    浏览(50)
  • [LeetCode周赛复盘] 第 111 场双周赛20230819

    T1 对向双指针。 T2 子序列/同向双指针。 T3 LIS/状态DP。 T4 数位DP。 2824. 统计和小于目标的下标对数目 1. 题目描述 2. 思路分析 类似两数之和,由于顺序无关,把数据排序。 设置l,r=0,n-1。 若a[l]+a[r]target,则a[l]+ 任意a[l+1…r]都target。则这r-l个数都可以和l组队。 3. 代码实现 2825

    2024年02月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包