蓝桥杯2023真题(4)

1.景区导游(树上前缀和、最近公共祖先)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

路线:2 -> 6 -> 5 -> 1
1.一个点都不去去掉的花费记作sum
2.去掉第一个点,sum - cost[2 -> 6]
3.去掉第二个点,sum - cost[2 -> 6] - cost[6 -> 5] + cost[2 -> 5]

dfs 中的参数不是一下就想到的,而是在写的过程中,你发现需要某个信息,而这个信息没有被提前记录,所以可以把这个信息当作参数记录下来

正解就是优化 cost 的求法

暴力 dfs(O(k * n))

#include<iostream>
#include<vector>
#include<map>
using namespace std;
const int N = 2e5 + 10;
map<pair<int, int>, int> st; // 存储两个点之间的时间
vector<pair<int, int>> g[N]; // 存储图和时间
int n, k;
int a[N];// 起点、终点、当前节点、父节点、时间总和
bool dfs(int u, int v, int s, int fa, int sum){if(s == v){st[make_pair(u, v)] = sum;st[make_pair(v, u)] = sum;return true;}for(int i = 0; i < g[s].size(); i++){// 子节点int son = g[s][i].first, w = g[s][i].second;// 如果子节点等于父节点,说明重复了跳过if(son == fa) continue;// 父节点为当前节点if(dfs(u, v, son, s, sum + w)) return true;}return false;
}int main(){scanf("%d%d", &n, &k);int u, v, t;for(int i = 0; i < n - 1; i++){scanf("%d%d%d", &u, &v, &t);g[u].push_back(make_pair(v, t));g[v].push_back(make_pair(u, t));}for(int i = 0; i < k; i++) scanf("%d", &a[i]);int ans = 0;for(int i = 1; i < k; i++){dfs(a[i - 1], a[i], a[i - 1], -1, 0);ans += st[make_pair(a[i - 1], a[i])];}for(int i = 0; i < k; i++){int res = ans;if(!i) res -= st[make_pair(a[i], a[i + 1])];else if(i == k - 1) res -= st[make_pair(a[i - 1], a[i])];else{res -= st[make_pair(a[i - 1], a[i])];res -= st[make_pair(a[i], a[i + 1])];dfs(a[i - 1], a[i + 1], a[i - 1], -1, 0);res += st[make_pair(a[i - 1], a[i + 1])];}printf("%d ", res);}return 0;
}

正解(O(n))

在这里插入图片描述

#include<iostream>
#include<vector>
using namespace std;
const int N = 2e5 + 10;
typedef long long qq;
vector<pair<int, int>> e[N];
// 存储父节点,存储深度,存储重儿子,存储以当前节点为根的子树节点数,存储当前节点的重链顶点
int fa[N], dep[N], son[N], sz[N], top[N]; 
qq sum[N]; // 存储树上前缀和
int a[N];
int n, k;// 求出 fa, dep, son, sz
void dfs1(int u, int father){fa[u] = father, dep[u] = dep[father] + 1, sz[u] = 1;for(auto v : e[u]){int s = v.first;if(s == father) continue;dfs1(s, u);sz[u] += sz[s];if(sz[son[u]] < sz[s]) son[u] = s;}
}// 求出 top
void dfs2(int u, int t){// 链头top[u] = t;// 没有重儿子if(!son[u]) return;// 搜重儿子dfs2(son[u], t);for(auto v : e[u]){int s = v.first;if(s == fa[u] || s == son[u]) continue;// 搜轻儿子dfs2(s, s);}
}// 求公共祖先
int lca(int u, int v){while(top[u] != top[v]){if(dep[top[u]] < dep[top[v]]) swap(u, v);u = fa[top[u]];}return dep[u] < dep[v] ? u : v;
}// 求树上前缀和
void cal_sum(int u){for(auto v : e[u]){int s = v.first, w = v.second;if(s == fa[u]) continue;sum[s] = sum[u] + w;cal_sum(s);}
}int main(){scanf("%d%d", &n, &k);int u, v, t;for(int i = 1; i < n; i++){scanf("%d%d%d", &u, &v, &t);e[u].push_back({v, t});e[v].push_back({u, t});}for(int i = 1; i <= k; i++) scanf("%d", &a[i]);dfs1(1, 0);dfs2(1, 1);cal_sum(1);qq ans = 0;for(int i = 2; i <= k; i++){int x = a[i - 1], y = a[i];qq cost = sum[x] + sum[y] - 2 * sum[lca(x, y)];ans += cost;}for(int i = 1; i <= k; i++){qq res = ans;int x = a[i - 1], y = a[i], z = a[i + 1];if(i == 1) res -= sum[y] + sum[z] - 2 * sum[lca(y, z)];else if(i == k) res -= sum[x] + sum[y] - 2 * sum[lca(x, y)];else{res -= sum[x] + sum[y] - 2 * sum[lca(x, y)];res -= sum[y] + sum[z] - 2 * sum[lca(y, z)];res += sum[x] + sum[z] - 2 * sum[lca(x, z)];}printf("%lld ", res);}return 0;
}

2.砍树(树上差分、最近公共祖先)

在这里插入图片描述
在这里插入图片描述

思路

dfs 找到两个点之间的路径,然后打上标记,如果打上 m 个标记,那么就可以作为答案

正解:优化打标记的过程,边权转换为点权,每个边权为子节点的点权
第一步:给路径的起点和终点都加 1
第二步:给两个点的最近公共祖先减 2
第三步:树上差分
第四步:让每个点都加上他的子树和
点权等于这个点和他父节点相连的边权

暴力 dfs(O(n * m))

#include<iostream>
#include<vector>
#include<map>
using namespace std;
const int N = 2e5 + 10;
map<pair<int, int>, int> id; // 存储编号
vector<int> e[N];
int w[N]; // 存储边权
int n, m;bool dfs(int a, int b, int u, int fa){if(u == b) return true;for(int v : e[u]){if(v == fa) continue;if(dfs(a, b, v, u)){int t = id[{u, v}];w[t]++;return true;}}return false;
}int main()
{scanf("%d%d", &n, &m);int x, y;for(int i = 1; i < n; i++){scanf("%d%d", &x, &y);e[x].push_back(y);e[y].push_back(x);id[{x, y}] = i;id[{y, x}] = i;}int a, b;for(int i = 0; i < m; i++){scanf("%d%d", &a, &b);dfs(a, b, a, -1);}int ans = -1;for(int i = n - 1; i >= 1; i--){if(w[i] == m){ans = i;break;}}printf("%d", ans);return 0;
}

正解(O(n))

#include<iostream>
#include<vector>
#include<map>
using namespace std;
const int N = 2e5 + 10;
int fa[N], dep[N], son[N], sz[N], top[N];
map<pair<int, int>, int> id; // 存储编号
vector<int> e[N];
int w[N]; // 存储点权
int n, m;void dfs1(int u, int father){fa[u] = father, dep[u] = dep[father] + 1, sz[u] = 1;for(int v : e[u]){if(v == father) continue;dfs1(v, u);sz[u] += sz[v];if(sz[son[u]] < sz[v]) son[u] = v;}
}void dfs2(int u, int t){top[u] = t;if(!son[u]) return;dfs2(son[u], t);for(int v : e[u]){if(v == fa[u] || v == son[u]) continue;dfs2(v, v);}
}int lca(int u, int v){while(top[u] != top[v]){if(dep[top[u]] < dep[top[v]]) swap(u, v);u = fa[top[u]];}return dep[u] < dep[v] ? u : v;
}void lca_sum(int u, int father){for(int v : e[u]){if(v == father) continue;lca_sum(v, u);w[u] += w[v];}
}int main()
{scanf("%d%d", &n, &m);int x, y;for(int i = 1; i < n; i++){scanf("%d%d", &x, &y);e[x].push_back(y);e[y].push_back(x);id[{x, y}] = i;id[{y, x}] = i;}dfs1(1, 0);dfs2(1, 1);int a, b;for(int i = 0; i < m; i++){scanf("%d%d", &a, &b);// 树上差分w[a]++, w[b]++;w[lca(a, b)] -= 2;}lca_sum(1, 0);int ans = -1;for(int i = 1; i <= n; i++){if(w[i] == m){int t = id[{i, fa[i]}];ans = max(ans, t);}}printf("%d", ans);return 0;
}

3.三国游戏(贪心)

在这里插入图片描述
在这里插入图片描述

思路

因为事件是独立的,所以可以从大到小排序,看 a - b - c 的和最多有多少个满足大于0

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N], c[N], d[N];
int n;int f(int a[], int b[], int c[]){for(int i = 1; i <= n; i++) d[i] = a[i] - b[i] - c[i];sort(d + 1, d + n + 1, greater<int>());long long sum = 0;for(int i = 1; i <= n; i++){sum += d[i];if(sum <= 0){sum = i - 1;break;}}return sum > 0 ? sum : -1;
}int main()
{scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d", &a[i]);for(int i = 1; i <= n; i++) scanf("%d", &b[i]);for(int i = 1; i <= n; i++) scanf("%d", &c[i]);int res = max(f(a, b, c), max(f(b, a, c), f(c, a, b)));printf("%d", res);return 0;
}

4.填充(贪心)

在这里插入图片描述

思路

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{string s;cin>>s;int res = 0;for(int i = 1; i < s.size(); i++){if(s[i - 1] == s[i] || s[i - 1] == '?' || s[i] == '?'){res++;// 成对匹配,如果匹配成功,就跳过后面那个,到后面的后面,再匹配i++;}}cout<<res;return 0;
}

5.翻转(模拟)

在这里插入图片描述
在这里插入图片描述

思路

如果两边和当前位置相反,且和 t 不同,那就翻转,最后再比较 s 和 t 是否相同

#include <iostream>
using namespace std;
int main()
{int d;cin>>d;string t, s;while(d--){cin>>t>>s;int res = 0;for(int i = 1; i < s.size() - 1; i++){if(s[i] != t[i] && s[i - 1] != s[i] && s[i] != s[i + 1]){s[i] ^= 1;res++;}}if(s == t) cout<<res<<endl;else cout<<-1<<endl;}return 0;
}

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

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

相关文章

计算机网络笔记(湖科大教书匠版本)

第一章、 ①三种交换方式 电路交换、分组交换、报文交换&#xff08;被分组交换所取代&#xff09; 1.电路交换&#xff1a;会一直占用通道&#xff0c;不适合计算机之间的数据通信 2.分组交换&#xff1a;通常我们把表示该数据的整块数据称为一个报文。 先把较长的报文划…

下载、安装并配置 Node.js

文章目录 1. 下载2. 自定义安装3. 添加环境变量4. 验证5. 修改下载位置6. npm 换源7. 测试 ➡️➡️➡️来源&#xff1a;Simplilearn.com Node.js 是一个开源、跨平台的 JavaScript 运行时环境和库&#xff0c;用于在客户端浏览器之外运行 web 应用程序。 Ryan Dahl 在2009年开…

React useMemo钩子指南:优化计算性能

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

萝卜大杂烩 | Polars ,最强Pandas平替(内含实操代码,建议收藏!)

本文来源公众号“萝卜大杂烩”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Polars (最强Pandas平替) 本文章转自&#xff1a;数据studio 1 介绍 Polars是一个用于操作结构化数据的高性能DataFrame库&#xff0c;可以说是平替…

leetcode 热题 100_旋转图像

题解一&#xff1a; 翻转数组&#xff1a;先将数组沿右上-左下对角线翻转&#xff0c;再将数组上下翻转。 class Solution {public void rotate(int[][] matrix) {int n matrix.length;for (int i 0; i < n; i) {//沿右上-左下对角线翻转for (int j 0; j < n - i - 1…

简单句,并列句【语法笔记】

1. 简单句&#xff0c;并列句本质分别是什么 2. 如何区分简单句和并列句 3. 连接词 4. 简单句的五大基本句型 5. 有连接词&#xff0c;未必都是并列句&#xff0c;这是为什么

为何系统对接采用定制开发周期通常比集成平台更长

在信息化建设的浪潮中&#xff0c;系统对接是实现企业内外部系统间数据共享和业务协同的关键环节。在对接开发过程中&#xff0c;定制开发与平台开发是两种主要的实现方式&#xff0c;而普遍观点认为&#xff0c;定制开发对接的周期通常要比平台开发更长。本文将深入探讨这一现…

物奇平台超距断连无蓝牙广播问题解决方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 物奇平台超距断连无蓝牙广播问题解决方法 一 问题反馈 二解决方法: 1 运行流程分析 对应代…

智能合约开发基础知识:最小信任机制、智能合约、EVM

苏泽 大家好 这里是苏泽 一个钟爱区块链技术的后端开发者 本篇专栏 ←持续记录本人自学两年走过无数弯路的智能合约学习笔记和经验总结 如果喜欢拜托三连支持~ 专栏的前面几篇详细了介绍了区块链的核心基础知识 有兴趣学习的小伙伴可以看看http://t.csdnimg.cn/fCD5E关于区块…

线上又出问题了!又是特殊场景,哎呀,当时怎么没有想到!

目录标题 导读01.为什么经常会发生测试场景覆盖不全的问题?02.如何提升测试覆盖度?03.综述 导读 在我们的测试工作中&#xff0c;是不是经常遇到这样的情形&#xff0c;发生了线上问题&#xff0c;产品、研发或者测试同学一拍脑袋&#xff1a;当时怎么没有想到&#xff0c;怎…

Vue.js+SpringBoot开发海南旅游景点推荐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

【论文阅读】VMamba:视觉状态空间模型

文章目录 VMamba:视觉状态空间模型摘要相关工作状态空间模型 方法准备状态空间模型离散化选择扫描机制 2D 选择扫描VMamba 模型整体结构VSS块 实验分析实验有效感受野输入尺度 总结 VMamba:视觉状态空间模型 摘要 受最近提出的状态空间模型启发&#xff0c;我们提出了视觉状态…

一款适合程序员开发复杂系统的通用平台——JNPF 开发平台

在过去&#xff0c;很多开发工具更侧重代码编辑&#xff0c;针对数据库增删改查&#xff08;CRUD&#xff09;类的 Web 系统开发&#xff0c;在界面设计、前后端数据交互等环节主要还是靠写代码&#xff0c;效率比较低。目前很多所谓的低代码开发平台&#xff0c;大多数也都是基…

Linux第75步_pinctrl子系统驱动和gpio子系统的常用函数

1、STM32MP1的pinctrl子系统驱动 pinctrl子系统源码目录为drivers/pinctrl&#xff0c;一个PIN最好只能被一个外设使用。 “stm32mp151.dtsi”中有一个“pin-controller节点标签”叫pinctrl pinctrl: pin-controller50002000 { #address-cells <1>; /*定义子节点的…

【24春招/Java】Java的市场情况介绍及Spring Boot基础

Java的市场情况 需求减少 人员增加 面试难度增加 1、Java高级开发&#xff0c;100份简历&#xff0c;筛选了20份&#xff0c;邀约20个人面试 面试机会&#xff1a;录取人数20:1 充分准备通过面试的前提 不要裸面&#xff01;&#xff01;&#xff01; 背葵花宝典&#xff08;…

23.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-实现配置工具数据结构

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;22.加载配置文件…

站库分离技术--反向代理技术-雷池云WAF-给自己搭建一个安全点的网站

文章目录 概要整体架构流程技术名词解释技术细节ssh-ubuntu服务器docker-映射-链接-通信nginx反代mysql设置数据库新密码 小结我的mysql映射目录我的wordpress映射目录 成果展示 概要 新买了一个云服务器&#xff0c;想搭建一个站库分离的wordpress为主的网站&#xff0c;采用d…

PID控制器组(完整SCL代码)

PID控制器组不是什么新概念,是在PID控制器的基础上,利用面向对象的思想对对象进行封装 批量实例化。 1、增量式PID https://rxxw-control.blog.csdn.net/article/details/124363197https://rxxw-control.blog.csdn.net/article/details/1243631972、完全增量式PID https:/…

Vue 3:引领前端开发的未来

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

自制STLink-V2.1

STLink-V2.1需要使用的芯片是STM32F103CBT6 原理图如下&#xff1a; PCB如下&#xff1a; 将板子焊接好后下载&#xff1a;STM32 DebugMass storageVCP V2.J40.M27的固件后&#xff0c;再使用ST官方ST-LinkUpgrade工具对我们自制的STLink-V2.1进行升级。升级完成后&#xff0c…