第十四届蓝桥杯省赛真题解析(含C++详细源码)

第十四届蓝桥杯省赛

  • 整数删除
    • 满分思路及代码
      • solution1 (40% 双指针暴力枚举)
      • solution 2(优先队列+模拟链表 AC)
  • 冶炼金属
    • 满分代码及思路
  • 子串简写
    • 满分思路及代码
      • solution 1(60% 双指针)
      • solution 2(二分 AC)
  • 岛屿个数
    • 满分代码及思路
  • 飞机降落
    • 满分思路及代码
  • 接龙数列
    • 满分思路及代码

整数删除

在这里插入图片描述
题目链接

满分思路及代码

solution1 (40% 双指针暴力枚举)

#include <iostream>
using namespace std;
const int N=5e5+10;
int n,k;
int a[N];
int main()
{cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i];}//实际上我们并不能通过简单的排序来找到数列中最小的整数//因为这样会失去原来的相对位置 而导致删去后的增加操作出错//所以我们可以用双指针的思路来写while(k--){int l=1;int r=n;while(l!=r){if(a[l]<=a[r]){r--;}else{l++;}}//遍历整个数组寻找最小值if(l==1){a[l+1]+=a[l];}else if(l==n){a[l-1]+=a[l];}else{a[l+1]+=a[l];a[l-1]+=a[l];}//删除 覆盖掉for(int i=l;i<=n;i++){a[i]=a[i+1];}n--;
}for(int i=1;i<=n;i++){cout<<a[i]<<' ';}return 0;
}

solution 2(优先队列+模拟链表 AC)

思路参考:
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
// 记录每个位置的数是否被删除过
bool removed[500005];
// 数据过大,爆int
#define ll long long
int main()
{int n, k;cin >> n >> k;// 数列,数和左右相邻的数的距离vector<pair<ll, pair<int, int>>> a(n);// 优先队列,数和下标priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> p;int t;for (int i = 0; i < n; i++){cin >> t;// 相邻的数初始距离为1a[i] = {t, {1, 1}};// 数和下标压入堆p.push({t, i});}//查找k次while (k){// 弹出第一个数pair<ll, int> tp = p.top();p.pop();ll value = tp.first;int index = tp.second;// 如果已经被删除过,或者被修改过,则跳过,否则删除if (removed[index] || a[index].first != value)continue;// 标记为已删除removed[index] = true;// 左右最近未被删除节点到自己的距离int l = index - a[index].second.first;int r = index + a[index].second.second;// 如果左边相邻的数存在则更新if (l >= 0 && !removed[l]){// 更新左边的数并压入堆a[l].first += value;p.push({a[l].first, l});// 如果右边的数存在,则更新左边的数到右边的距离if (r < n && !removed[r]){a[l].second.second += a[index].second.second;}}// 如果右边相邻的数存在则更新if (r < n && !removed[r]){// 更新右边的数并压入堆a[r].first += value;p.push({a[r].first, r});// 如果左边的数存在,则更新右边的数到左边的距离if (l >= 0 && !removed[l]){a[r].second.first += a[index].second.first;}}k--;}// 输出还未被删除的数for (int i = 0; i < n; i++){if (!removed[i])cout << a[i].first << " ";}return 0;
}

冶炼金属

在这里插入图片描述

满分代码及思路

//对于这个v的范围我们怎么来确定呢
//我觉得是这样的 例如投入75个O产出3个X
//如果最好的情况即浪费的最少得时候 即V=25 当然也有小数的情况 但也就是直接相除之后向下取整就好 最后对于每一次冶炼的V取max
//最坏的情况需要考虑 还是拿上面的举例 我们可以从产出4个X所需要的V枚举到3 最后取min 但是注意此时就需要向上取整即加1;
//因为我们是在找不符合75个出3个X的临界点 即多少O出4个X

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int a[N],b[N];
int n;
int maxval=1e9;
int minval=0;
int main()
{cin>> n;for(int i=0;i<n;i++){cin>>a[i]>>b[i];}for(int i=0;i<n;i++){maxval=min(a[i]/b[i],maxval);minval=max(a[i]/(b[i]+1)+1,minval);}cout<<minval<<' '<<maxval;return 0;
}

子串简写

在这里插入图片描述

题目链接

满分思路及代码

solution 1(60% 双指针)

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>using namespace std;// 双指针方法
int TwoPointers(int K, const string& S, char c1, char c2) {int n = S.length();int count = 0;for (int left = 0; left < n; ++left) {if (S[left] == c1) {for (int right = left + K - 1; right < n; ++right) {if (S[right] == c2) {++count;}}}}return count;
}
//首先暴力的思路类似于双指针 
//三种情况
//我们用p指针找到C1 保持c1不动移动指针q 让q不断去找c2 直到满足我们的长度我们的res++
//然后q走到最后一个c2了之后移动p 规则一样
//p q一起动
//
int main() {int K;string S;char c1, c2;// 读取输入cin >> K;cin >> S >> c1 >> c2;// 计算结果int result=TwoPointers(K, S, c1, c2);cout << result << endl;return 0;
}

solution 2(二分 AC)

#include<iostream>
#include<algorithm>
using namespace std;
int nec1[500100];
int c1dx = 0;
int c2dx = 0;
int nec2[500100];
int main()
{int k;cin >> k;string str;cin >> str;str = "1" + str;char c1, c2;cin >> c1 >> c2;for (int i = 1; i < str.length(); i++) {//记录c1字符所有出现的位置if (str[i] == c1) {nec1[c1dx] = i;c1dx++;}//记录c2字符所有出现位置if (str[i] == c2) {nec2[c2dx] = i;c2dx++;}}long long ans = 0;//枚举c1字符出现的位置for (int i = 0; i < c1dx; i++) {//二分查找c2字符出现的位置的合法位置auto dx = lower_bound(nec2, nec2 + c2dx, nec1[i] + k-1);//没有找到情况if (dx == nec2 + c2dx)continue;//找到了int t = dx - nec2;//加上总合法个数ans += c2dx - t;}cout << ans << endl;return 0;
}

岛屿个数

在这里插入图片描述

题目链接

满分代码及思路

在我之前的文章 搜索系列 里面可以找到详细分析

#include <bits/stdc++.h> 
using namespace std;
const int X = 50 + 10;
typedef pair<int, int> PII;
int grid[X][X];  // 使用 int 类型数组
int n, m, T;
int ans;
int s[X];
// 海的移动偏移量数组
int dx[8] = {-1,-1,-1,0,1,1,1,0};
int dy[8] = {-1,0,1,1,1,0,-1,-1};
// 陆地的移动偏移量
int DX[4] = {-1, 0, 1, 0};
int DY[4] = {0, 1, 0, -1};
bool st_land[X][X];
bool st_sea[X][X];bool check(int x, int y) {if (x < n && x >= 0 && y < m && y >= 0) {return true;}return false;
}// 找到了(x,y)所在的岛屿 并将该岛屿的所有点都标为了 true
void bfs_land(int u, int v) {queue<PII> Q;st_land[u][v] = true;PII tp = {u, v};Q.push(tp);while (!Q.empty()) {PII t = Q.front();Q.pop();for (int i = 0; i < 4; i++) {int nu = t.first + DX[i];int nv = t.second + DY[i];if (check(nu, nv) && grid[nu][nv] == 1 && !st_land[nu][nv]) {st_land[nu][nv] = true;Q.push({nu, nv});}}}
}void bfs_sea(int x, int y) {queue<PII> q;PII tmp = {x, y};q.push(tmp);st_sea[x][y] = true;while (!q.empty()) {PII p = q.front();q.pop();for (int i = 0; i < 8; i++) {  // 枚举一下海的方向  int nx = p.first + dx[i];int ny = p.second + dy[i];if (!check(nx, ny) || st_sea[nx][ny]) {continue;}if (grid[nx][ny] == 0) {st_sea[nx][ny] = true;q.push({nx, ny});} else if (grid[nx][ny] == 1 && !st_land[nx][ny]) {ans++;bfs_land(nx, ny);  // 如果发现寻找外海的过程中发现了陆地 说明属于新的外岛那么需要找到与他相连的全部陆地}}}
}int main() {cin >> T;while (T--) {cin >> n >> m;ans = 0;  // 每次都需要重置一下for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {st_sea[i][j] = st_land[i][j] = false;}}for (int i = 0; i < n; i++) {string s;cin >> s;for (int j = 0; j < m; j++) {grid[i][j] = s[j] - '0';  // 将字符转化成数字存进去}}bool has_sea = false;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (i == 0 || i == n - 1 || j == 0 || j == m - 1) {if (!st_sea[i][j] && grid[i][j] == 0) {  // 当前的这个点是海并且是没有被标记过has_sea = true;bfs_sea(i, j);}}}}// 判断全是陆地的特例(只有一个大岛)if (!has_sea) {ans = 1;}cout << ans << endl;}return 0;
}

飞机降落

在这里插入图片描述
题目链接

满分思路及代码

思路直接去看我之前的文章就好:搜索系列
非常详细具体
视频讲解:非常牛逼

#include <bits/stdc++.h>
using namespace std;
const int N =10+9;//防止越界
int n;//有多少架飞机
//int T,D,L;//分别表示降落时刻,能盘旋的时间,降落的时间
//考虑到这题这三个数据可以代表一架飞机的属性 可以考虑采用结构体来实现struct plane{
int t;
int d;
int l;
}p[N];
bool s[N];//每架飞机的状态
//我们需要知道几架飞机成功降落 和前一架飞机降落的时间
bool dfs(int x,int time)
{if(x>=n){return true;}//递归出口//枚举每种降落顺序for(int i=0;i<n;i++){if(!s[i])//这架飞机没有安排过{s[i]=true;if(p[i].t+p[i].d<time)//燃尽了也没等到前一架飞机降落完毕{//回溯s[i]=false;return false;}int next=max(p[i].t,time)+p[i].l;//核心 两种情况的综合//即一来就可以落 和 需要等前一架降落完毕再落if(dfs(x+1,next)){return true;//后续的飞机都可以顺利降落}s[i]=false;}}return false;//所有降落方案都不能成功降落;}
int main()
{int T;//测试的组数cin>>T;while(T--){cin>>n;for(int i=0;i<n;i++){cin>>p[i].t>>p[i].d>>p[i].l;}if(dfs(0,0)){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}for(int i=0;i<n;i++){s[i]=false;}}return 0;}

接龙数列

在这里插入图片描述

题目链接

满分思路及代码

其实我们需要转化题目所问的问题
题目问的是 最少需要删除几个字符或者说数字 等价于求数列最长是多少 ——最长子序列问题
思路参考:视频讲解

#include <iostream>
using namespace std;
const int N = 1e5;
int a[N]; //也可以使用vector,但在效率上会有损失
int dp[10];//全局变量,全部默认初始化为0
int main()
{
int n;
cin >> n;
for (int i = 0;i < n;i++)
{
cin >> a[i];
}
//拆分每一个数,取出首位数字和末位数字
int front, tail;
for (int i = 0;i < n;i++)
{
int cur = a[i];
tail =cur % 10;
front =tail;
while (cur)
{
front = cur%10;
cur= cur / 10;
}
dp[tail] = dp[tail] > dp[front] + 1 ? dp[tail] : dp[front ]+ 1;
}
//找最大的dp数组元素值
int maxLen = 0;
for (int i = 0;i < 10;i++)
{
if (dp[i] > maxLen)
maxLen = dp[i];
}
cout << n - maxLen << endl;
return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Matlab:三维绘图

目录 1.三维曲线绘图命令&#xff1a;plot3 实例——绘制空间直线 实例——绘制三角曲线 2.三维曲线绘图命令&#xff1a;explot3 3.三维网格命令&#xff1a;mesh 实例——绘制网格面 实例——绘制山峰曲面 实例——绘制函数曲线 1.三维曲线绘图命令&#xff1a;plot3 …

(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)

源代码 如上图将7个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?…

React框架的Concurrent Mode

以下是关于 Concurrent Mode 的系统梳理: 一、Concurrent Mode 的诞生背景 传统渲染的局限性 同步阻塞:React 15 的 Stack Reconciler 无法中断渲染流程优先级缺失:用户交互与后台任务同等对待资源竞争:网络请求与渲染任务无法智能调度核心设计目标 可中断渲染:允许高优先…

Java 集合框架与 Stream 流深入剖析(重点详细讲解)

目录 引言 一、ArrayList 1. 概述 2. 特点 动态扩容 初始容量 扩容倍数 随机访问高效 插入和删除效率低 3. 代码示例 4. 分析 二、HashSet 1. 概述 2. 特点 唯一性 插入、删除和查找效率高 无序性 3. 代码示例 4. 分析 三、HashMap 1. 概述 2. 特点 键唯…

Golang的Goroutine(协程)与runtime

目录 Runtime 包概述 Runtime 包常用函数 1. GOMAXPROCS 2. Caller 和 Callers 3. BlockProfile 和 Stack 理解Golang的Goroutine Goroutine的基本概念 特点&#xff1a; Goroutine的创建与启动 示例代码 解释 Goroutine的调度 Gosched的作用 示例代码 输出 解…

【51单片机】3-3【定时器/计数器/中断】超声波测距模块测距

1.硬件 51最小系统超声波测距模块 2.软件 #include "reg52.h"//距离小于10cm,D5亮&#xff0c;D6灭&#xff0c;反之相反现象sbit D5 P3^7;//根据原理图&#xff08;电路图&#xff09;&#xff0c;设备变量led1指向P3组IO口的第7口 sbit D6 P3^6;//根据原理图&…

2-Visual Studio 2022 NET开发Windows桌面软件并连接SQL Server数据库

引言 今天尝试Visual Studio 2022 NET开发一个NET桌面软件&#xff0c;并尝试连接SQL Server的数据库&#xff0c;此文章为开发笔记。 --------------------------------------------------------------------------------------------------------------------------------- …

Kafka 漏消费和重复消费问题

Kafka 虽然是一个高可靠、高吞吐的消息系统&#xff0c;但如果使用不当&#xff0c;**“漏消费”和“重复消费”**问题是非常容易发生的&#xff0c;尤其在业务系统中会造成数据丢失、重复写库等严重问题。 &#x1f3af; 一句话理解&#xff1a; Kafka 本身提供 “至多一次”…

【大模型深度学习】如何估算大模型需要的显存

一、模型参数量 参数量的单位 参数量指的是模型中所有权重和偏置的数量总和。在大模型中&#xff0c;参数量的单位通常以“百万”&#xff08;M&#xff09;或“亿”&#xff08;B&#xff0c;也常说十亿&#xff09;来表示。 百万&#xff08;M&#xff09;&#xff1a;表示…

LeetCode算法题(Go语言实现)_32

题目 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪生节点&#xff0c;节点 1 是…

Linux makefile的一些语法

一、定义变量 1. 变量的基本语法 在 makefile 中&#xff0c;变量的定义和使用非常类似于编程语言中的变量。变量的定义格式&#xff08;最好不要写空格&#xff09;如下&#xff1a; VARIABLE_NAMEvalue 或者 VARIABLE_NAME:value 表示延迟赋值&#xff0c;变量的值在引…

CAN/FD CAN总线配置 最新详解 包含理论+实战(附带源码)

看前须知&#xff1a;本篇文章不会说太多理论性的内容&#xff08;重点在理论结合实践&#xff09;&#xff0c;顾及实操&#xff0c;应用&#xff0c;一切理论内容支撑都是为了后续实际操作进行铺垫&#xff0c;重点在于读者可以看完文章应用。&#xff08;也为节约读者时间&a…