蓝桥杯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.rhkb.cn/news/273695.html

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

相关文章

01、python_爬虫的相关概念

一、什么是爬虫&#xff1f; 爬虫是网络爬虫的简称&#xff0c;指的是一种自动化程序&#xff0c;用于在互联网上抓取信息。爬虫的核心工作包括爬取网页、解析数据和存储数据。 通俗来说就是&#xff1a;通过一个程序&#xff0c;根据url(http://taobao.com)进行爬取网页&…

蓝桥杯练习系统(算法训练)ALGO-980 斐波那契串

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;10.0s Java时间限制&#xff1a;30.0s Python时间限制&#xff1a;50.0s 问题描述 斐波那契串由下列规则生成&#xff1a;   F[0] "0";   F[1] "1";   F[n] F[n-1] F[n-2]…

Tomcat容器经常重启问题排查

报错代码: INFO [Catalina-utility-2] org.apache.catalina.core.StandardContext.reload Reloading Context with name [] has started1.查看内存占用情况:top 可以发现java线程正常情况下占用高达24%的内存资源 2.继续排查:top -Hp 29580 可以发现主要有子线程Catalina-ut…

OWASP Top 10 网络安全10大漏洞——A02:A02:2021-加密机制失效

10大Web应用程序安全风险 2021年top10中有三个新类别、四个类别的命名和范围变化&#xff0c;以及一些合并。 A02&#xff1a;A02:2021-加密机制失效 上升一个位置&#xff0c;当前top2&#xff0c;以前称为敏感数据泄露&#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…

伊理威科技:新手开抖店的教程

在数字浪潮中&#xff0c;抖音小店如星火燎原&#xff0c;吸引无数创业者。你是否也心潮澎湃&#xff0c;想要一试身手?别急&#xff0c;让我们一步步揭开开店的神秘面纱。 注册流程。想象一下&#xff0c;你只需在抖音平台上点击“我要开店”&#xff0c;按提示填写相关信息&…

Upload 上传(图片/文件),回显(图片),下载(文件)

1.前端技术&#xff1a;V3 Ant Design Vue 2.后端技术&#xff1a;Java 图片上传/回显&#xff1a; 文件上传回显&#xff1a; 表结构&#xff1a;单文件/图片上传为A表对文件C表 &#xff08;A表field字段 对应 C表id字段&#xff09; 如图&#xff1a;A表中的 vehicle_d…

Excel小技巧 (4) - 如何转换数字到人民币文字

选中数字&#xff0c;点击鼠标右键&#xff0c;《设置单元格式》 分类选中特殊&#xff0c;并选择中文大写数字 就转好了&#xff01; 再教一个小技巧&#xff0c;最近东南亚项目也多起来了&#xff0c;是不是需要打印invoice上有泰文的数字。 强大的Excel也有个公式

揭秘PostgreSQL:超越传统数据库的无限可能!

介绍&#xff1a;PostgreSQL是一个功能强大的开源对象关系数据库系统。以下是对PostgreSQL的详细介绍&#xff1a; 开源性&#xff1a;PostgreSQL是完全开源的&#xff0c;这意味着任何人都可以自由地获取、使用和修改它的源代码。 可定制性&#xff1a;它具有高度可定制性&…

傅里叶变换pytorch使用

参考视频&#xff1a;1 傅里叶变换原理_哔哩哔哩_bilibili 傅里叶变换是干嘛的&#xff1a; 傅里叶得到低频、高频信息&#xff0c;针对低频、高频处理能够实现不同的目的。 傅里叶过程是可逆的&#xff0c;图像经过傅里叶变换、逆傅里叶变换后&#xff0c;能够恢复到原始图像…

资料下载-嵌入式 Linux 入门

学习的第一步是去下载资料。 1. 有哪些资料 所有资料分 4 类&#xff1a; ① 开发板配套资料(原理图、虚拟机的映像文件、烧写工具等)&#xff0c;放在百度网盘 ② 录制视频过程中编写的文档、源码、图片&#xff0c;放在 GIT 仓库 ③ u-boot、linux 内核、buildroot 等比较大…

SpringBoot学习之自定义注解和AOP 切面统一保存操作日志(二十九)

一、定义一个注解 这个注解是用来控制是否需要保存操作日志的自定义注解(这个类似标记或者开关) package com.xu.demo.common.anotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; i…

llc如何实现开关管ZVS(零电压)导通

对于LLC而言最大的优势就是实现原边开关管 ZVS开通以及副边二极管ZCS关断来提高效率的&#xff0c;我们可以先来看如何实现开关管 ZVS开通 稳态下的分析 上图是LLC谐振腔中的大致电压与电流波形&#xff0c;我们可以在这个波形上来分析 MOS是如何实现ZVS开通的 注意&#xff…

原生JavaScript,根据后端返回JSON动态【动态列头、动态数据】生成表格数据

前期准备&#xff1a; JQ下载地址&#xff1a; https://jquery.com/ <!DOCTYPE html> <html><head><meta charset"utf-8"><title>JSON动态生成表格数据,动态列头拼接</title><style>table {width: 800px;text-align: cen…

谷粒商城【成神路】-【10】——缓存

目录 &#x1f9c2;1.引入缓存的优势 &#x1f953;2.哪些数据适合放入缓存 &#x1f32d;3.使用redis作为缓存组件 &#x1f37f;4.redis存在的问题 &#x1f9c8;5.添加本地锁 &#x1f95e;6.添加分布式锁 &#x1f95a;7.整合redisson作为分布式锁 &#x1f697…

php调用guzzlehttp库时出现Segmentation fault的解决方案

先说结论&#xff0c;这个问题的原因是因为php7.4与openssl3不兼容产生的&#xff0c;解决方案如下&#xff1a; 输入openssl version -a查看openssl版本&#xff0c;如果是3以上的版本与php7.4不兼容&#xff0c;7.4以下的没测试过&#xff0c;估计也有问题。我最终是安装上了…

深入理解Vue.js中的nextTick:实现异步更新的奥秘

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

微信小程序开发系列(二十)·wxml语法·setData()修改对象类型数据、ES6 提供的展开运算符、delete和rest的用法

目录 1. 新增单个、多个属性 1.1 新增单个属性 1.2 新增多个属性 2. 修改单个、多个属性 2.1 修改单个属性 2.2 修改多个属性 3. 优化 3.1 ES6 提供的展开运算符 3.2 Object.assign()将多个对象合并为一个对象 4. 删除单个、多个属性 4.1 删除单个属性 …

【Redis】RedisTemplate序列化传输数据

使用自定义的序列化器 使用RedisTemplate默认的序列化器发送数据&#xff0c;会将key全都当成Object处理&#xff0c;从而按照对象的方式转成json格式发送到服务器&#xff0c;这样会导致两个问题。一是不方便阅读&#xff0c;二是会大大浪费内存。因此&#xff0c;建议自定义…

MySQL常见的索引类型介绍

我将为您详细讲解 MySQL 中常见的索引类型&#xff0c;以及它们的使用场景、特点、区别和优势。索引是提高数据库查询性能的关键工具&#xff0c;它可以加速数据检索速度&#xff0c;减少服务器的负担。在 MySQL 中&#xff0c;索引类型主要包括 B-Tree 索引、哈希索引、全文索…