AtCoder Beginner Contest 428 ABCDE 题目解析

news/2025/10/18 23:25:57/文章来源:https://www.cnblogs.com/stelayuri/p/19150301

A - Grandma's Footsteps

题意

下课铃响起后,高桥会立即开始重复执行以下动作:

  • 以每秒 \(S\) 米的速度跑 \(A\) 秒,然后保持静止 \(B\) 秒。

请问在下课铃响后 \(X\) 秒时,他总共跑了多少米?

思路

\(A+B\) 秒为一个完整周期,共 \(\lfloor\dfrac{X}{A+B}\rfloor\) 个完整周期,对总距离的贡献为 \(\lfloor\dfrac{X}{A+B}\rfloor \times (S \times A)\)

最后讨论剩余的不完整周期(共 \(X \bmod (A+B)\) 秒)是否对总距离有贡献即可。

代码

void solve()
{int s, a, b, x;cin >> s >> a >> b >> x;int ans = (x / (a + b)) * (s * a);x %= a + b;if(x <= a) // 最后一个周期不足 a 秒,按剩余秒数计算ans += s * x;else // 超过 a 秒时按 a 秒计算ans += s * a;cout << ans;
}

B - Most Frequent Substrings

题意

给定一个长度为 \(N\) 的仅由小写英文字母组成的字符串 \(S\) 以及一个整数 \(K\)

对于一个长度为 \(K\) 的字符串 \(t\),定义其出现次数为满足以下条件的整数 \(i\) 的个数:

  • \(1 \leq i \leq N-K+1\)
  • \(S\) 字符串的第 \(i\) 个字符到第 \(i+K-1\) 个字符所形成的子串,与字符串 \(t\) 相同

求在所有长度为 \(K\) 的字符串中的出现次数最大值 \(x\),同时按照字典序升序输出所有长度为 \(K\) 且出现次数为 \(x\) 的字符串。

思路

可以借助 string 容器进行快速的子串截取,借助 map 容器进行自动排序以及次数统计,方便地完成本题。

代码

void solve()
{int n, k;string s;map<string, int> cnt;cin >> n >> k;cin >> s;int maxx = 0;for(int i = 0; i + k - 1 < n; i++){string t = s.substr(i, k); // [i, i+k-1] 形成的子串maxx = max(maxx, ++cnt[t]);}cout << maxx << "\n";for(auto it : cnt)if(it.second == maxx) // 当前字符串出现次数 = 最大出现次数cout << it.first << " ";
}

C - Brackets Stack Query

题意

一个字符串 \(T\) 被称为一个“好的括号序列”,当且仅当满足以下条件:

  • \(T\) 可以通过重复下面的操作 0 次或多次变成一个空字符串:

    • 每次在 \(T\) 中选择 () 这一连续子串,并将其删除。

有一个字符串 \(S\)。最初,\(S\) 是个空字符串。

请按照给出的顺序处理 \(Q\) 次操作。在每次操作后,判断当前的字符串 \(S\) 是否是一个好的括号序列。

操作有两种类型:

  • 1 c:给出一个字符 \(c\),保证 \(c\)() 中的一种。将 \(c\) 添加到字符串 \(S\) 的末尾。
  • 2:删除 \(S\) 的最后一个字符。保证此时 \(S\) 不是空字符串。

思路

栈的模拟题。

假如本题仅包含添加操作而没有删除操作,为了判断字符串是否是括号匹配的序列,只需要用一个栈,在每次添加左括号时将其进栈,每次添加右括号时判断栈内是否存在左括号能与其匹配即可。只要在最后栈是空的,且过程中每次出现右括号均有对应左括号能匹配,那么就可以判断当前字符串就是括号匹配的。

因为本题仅出现小括号这一种括号,所以每次只要栈内有左括号就可以直接与其相匹配,所以这一步我们可以直接优化成用单个变量 \(x\) 来模拟表示栈内的括号情况。每次加一个左括号则 \(x := x+1\),每次加一个右括号则 \(x:=x-1\)

括号匹配的条件即最后栈为空,且过程中每次从出现右括号都有对应左括号与其匹配,因此需要保证最后 \(x = 0\) 且过程中 \(x \ge 0\) 均成立。所以这一步我们只需要再来个变量 \(mi\) 存储 \(x\) 在过程中出现的最小值,保证最后 \(x = 0\)\(mi=0\) 即可。

然后考虑本题的删除操作。删除操作无非就是撤销上一次添加操作。所以我们还需要知道每一步添加操作完成之后,\(x\)\(mi\) 两个变量的值分别是多少。可以用两个栈来分别维护 \(x\)\(mi\) 这两个变量的变化,添加操作就往栈顶加新数字,删除操作则弹出栈顶即可。

代码

void solve()
{int q;cin >> q;stack<int> sk1; // 存储每一次操作后的 x 的值,栈顶即当前 xstack<int> sk2; // 存储 sk1 的前缀最小值 mi,栈顶即当前 misk1.push(0); // x 初始值为 0sk2.push(0);while(q--){int op;cin >> op;if(op == 1){char c;cin >> c;if(c == '('){int x = sk1.top() + 1; // x = x + 1sk1.push(x);sk2.push(min(sk2.top(), x));}else{int x = sk1.top() - 1; // x = x - 1sk1.push(x);sk2.push(min(sk2.top(), x));}}else{sk1.pop();sk2.pop();}if(sk1.top() == 0 && sk2.top() == 0) // x == 0 && mi == 0cout << "Yes\n";elsecout << "No\n";}
}

D - 183184

题意

对于正整数 \(x\)\(y\) ,定义 \(f(x,y)\) 如下:

  • \(x\)\(y\) 转为十进制字符串前后拼接后,再转回对应的十进制数值。

例如, \(f(3,14)=314,\ f(100,3)=1003\)

给定两个正整数 \(C\)\(D\) 。求满足以下条件的整数 \(x\) 的个数:

  • \(1 \leq x \leq D\)
  • \(f(C, C+x)\) 是一个完全平方数。

思路

我们考虑 \(C+x\) 这个数字的位数。假设位数为 \(d\),那么 \(f(C, C+x)\) 就可以通过 \(10^d \times C + (C+x)\) 来获得,相当于让 \(C\) 向高位移动 \(d\) 位后再让 \(C+x\) 拼在其后。

位数固定后,我们便可以计算相同位数的完全平方数个数。

已知由 \(d\) 位组成的整数的数值范围在 \(10^{d-1} \sim 10^d - 1\) 之间,可以定义出两个变量:

  • \(L = 10^d \times C + 10^{d-1}\)
  • \(R = 10^d \times C + (10^d - 1)\)

用于表示以 \(C\) 作为高位,且低位位数为 \(d\) 时的所有可能数值的范围。

但因为 \(x\) 受到 \(1 \le x \le D\) 的影响,所以这两个变量需要对其可行范围进行限制:

  • \(L = \max(L, 10^d \times C + (C+1))\)
  • \(R = \min(R, 10^d \times C + (C+D))\)

已知在 \(1 \sim T\) 的范围内,完全平方数的数量可以直接通过 \(\lfloor \sqrt T \rfloor\) 计算得出。因此为了计算 \(L \sim R\) 范围内的完全平方数,可以借助前缀和思想,通过 \(\lfloor \sqrt R \rfloor - \lfloor \sqrt {L-1} \rfloor\) 来获得。

单组数据时间复杂度 \(O(\log (C+D))\),注意取平方根在数值范围较大时不能直接用 sqrt 计算,会因为精度误差出错。推荐借助二分找平方根,或者使用 long double 类型的 sqrtl 函数。

代码

typedef long long ll;// 根号 n 向下取整
// 推荐二分,或根号函数用 long double 的 sqrtl
ll sqt(ll n)
{return sqrtl(n);
}void solve()
{ll C, D;cin >> C >> D;ll ans = 0;ll a = 1, b = 9, x = 10;// 假设位数 d 从 1 开始变大// 用 x 表示 10^d// [a, b] 表示位数为 d 时的最小最大值while(a <= C + D) // 低位最小值还没超过可行最大值 C+D 时{ll l = max(a, C + 1) + C * x; // 可行范围ll r = min(b, C + D) + C * x;if(l <= r)ans += sqt(r) - sqt(l - 1);a = a * 10; // 位数变大一位后 abx 的变化b = b * 10 + 9;x = x * 10;}cout << ans << "\n";
}signed main()
{ll t;cin >> t;while(t--)solve();return 0;
}

E - Farthest Vertex

题意

有一棵共 \(N\) 个点的树,每个点分别编号为 \(1\)\(N\) 。 第 \(i\) 条边连接 \(A_i\)\(B_i\) 两点。

定义点 \(u\)\(v\) 之间的距离为 \(u\)\(v\) 的简单路径上的边数。

对于每个 \(v = 1, 2, \dots, N\),解决以下问题:

  • 在顶点 \(1, 2, \dots, N\) 中,输出与顶点 \(v\) 距离最大的顶点的编号。如果有多个顶点满足条件,则输出编号最大的顶点

思路

(本题可以借助树的直径的性质分类讨论来简单地获取答案),下面分析另一种借助换根DP的做法。

如果我们假定 \(1\) 号点作为整棵树的根结点,将其拎起,然后考虑每个结点 \(u\) 到树上与其距离最远的结点之间的距离以及结点编号如何获得。

很明显,距离 \(u\) 最远的点要么是当前点的子树内部的某个叶子结点,要么是在子树外部(即答案在父结点方向,此时可以看作将根结点换为 \(u\) 点)。

  • 如果答案在子树内,我们可以在深搜完所有的子结点之后,在所有上传的答案中取个最大值来获得。
  • 如果答案在子树外,那么我们可以在深搜 \(u\) 的时候,让其父结点下传一个不在 \(u\) 的子树内部的点到 \(u\) 的最远距离及其编号的信息作为深搜参数,以此把父结点当作 \(u\) 的某个子结点来传递答案,实现换根。

所以先考虑对于树上每个结点 \(u\),从它出发往每个子结点的方向走,能走的最远距离以及到达的结点最大编号,通过一遍深搜进行求解。将每个儿子返回的结果存储在一个 vector 容器 \(A[u]\) 内。

在所有结点往子树方向的答案全部得出后,进行第二次深搜进行最终答案的求解。

对于根结点 \(1\),其没有父结点方向的答案来源,答案只存在于子结点方向,取 \(A[1]\) 内的最大答案即可。

然后考虑往子结点搜索。假如当前站在 \(u\) 点上,考虑搜索 \(v\) 这个子结点的答案:

  • 如果当前 \(u\) 点的答案来源(距离 \(u\) 点最远的点)不在 \(v\) 的子树内部,那么对于 \(v\) 点而言,其父结点方向与其距离最远的点,可以直接继承自当前 \(u\) 点的答案。
  • 如果当前 \(u\) 点的答案来源在 \(v\) 的子树内部,这不符合上面对于这一步深搜传参的定义(要保证参数的答案不在子树内),所以这里需要重新取 \(u\) 点的次大答案及其父结点方向的答案中的较大值作为传参。

接下来对于不是根结点的每个结点,其只需要在子树内部答案最大值以及父结点方向传参之间再挑选一个最大值作为最终答案即可。

时间复杂度 \(O(N \log N)\)

代码

int n;
vector<int> G[500005]; // 邻接表存图vector<pii> A[500005]; // A[i] 表示 i 到 每个子结点的 子树内部某一结点的 最远距离 及其编号
pii ret[500005]; // ret[i] 表示 dfs1 中 i 向父结点 return 的结果pii ans[500005]; // first 表示到其它点的距离最大值,second 表示点的编号// 返回 u 的子树内部 距离 u 最远的结点 与 u 之间的距离 及其编号
// first 表示距离,second 表示编号
pii dfs1(int u, int f)
{for(int &v : G[u]){if(v == f)continue;pii res = dfs1(v, u);res.first++; // 往上传递一层 最远距离+1A[u].push_back(res);}A[u].push_back(pii(0, u)); // 多放一个我到我自己的贡献,免去对叶子结点以及空数组的判断sort(A[u].begin(), A[u].end());return ret[u] = A[u].back(); // 返回 距离最大值及此时的结点编号
}// first 表示距离,second 表示编号
// 判断两个答案,取距离较大者,距离相同取编号较大者
pii checkMax(pii a, pii b)
{if(a.first > b.first || a.first == b.first && a.second > b.second)return a;return b;
}// 换根 dp,假设 u 为根
// ansf 表示不在 u 的子树内部的点到 u 的最远距离 及其编号
// first 表示距离,second 表示编号
void dfs2(int u, int f, pii ansf)
{ans[u] = checkMax(ansf, A[u].back());for(int &v : G[u]){if(v == f)continue;if(ret[v].second == ans[u].second) // v 方向是当前 ans[u] 的答案来源,不能直接传 ans[u]{// 要取 A[u] 的次大答案与 ansf 的较大值 作为新的 ansf 传递下去pii nxtf;nxtf = checkMax(ansf, A[u][A[u].size() - 2]);nxtf.first++; // 往下传递一层 最远距离+1dfs2(v, u, nxtf);}else{pii nxtf = ans[u];nxtf.first++; // 往下传递一层 最远距离+1dfs2(v, u, nxtf);}}
}void solve()
{cin >> n;for(int i = 1; i < n; i++){int a, b;cin >> a >> b;G[a].push_back(b);G[b].push_back(a);}dfs1(1, 0);dfs2(1, 0, pii(-1, 0));for(int i = 1; i <= n; i++)cout << ans[i].second << "\n";
}

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

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

相关文章

稻草火把下的星辰:回忆我的90年代求学路

1993年的夏天,我手握政和一中的录取通知书,却感觉这张纸比铅还重。中考成绩名列全校第一的喜悦,早已被无钱就读的现实冲刷得一干二净。在我们那个小村庄,考上高中并不被视为荣耀之事,唯有考上中专才被视为真正的“…

20251018

正睿 CSP 7 连测 终于 ak 了一场。 D 给定长度为 \(n(n \le 2 \times 10^5)\) 的序列 \(a(|a_i| \le 10^9)\)。若 \(a_i < 0\),\(b_i = -2^{-a_i}\);否则,\(b_i = 2^{a_i}\)。求 \(b\) 的最大子段和对 \(9982443…

Linux后门应急

Linux后门应急 1、主机后门用户名称:提交格式如:flag 进来先对终端升级一下 python -c import pty; pty.spawn("/bin/bash")直接使用cat /etc/passwd 查看后面用户flag{backdoor}2、主机排查项中可以发现到…

吴恩达深度学习课程一:神经网络和深度学习 第三周:浅层神经网络(二)

此分类用于记录吴恩达深度学习课程的学习笔记。 课程相关信息链接如下:原课程视频链接:[双语字幕]吴恩达深度学习deeplearning.ai github课程资料,含课件与笔记:吴恩达深度学习教学资料 课程配套练习(中英)与答案…

2025.10.18总结

今天继续学软考相关内容,看了操作系统一个章节进程管理的内容。 操作系统的定义:操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的划分,以提供给用户和其他软件方便的…

C++动态多态原理分析

class Animal { public:void speak() {cout << "Animal.speak()" << endl;} };class Cat :public Animal {void speak() {cout << "Cat.speak()" << endl;} }; void doW…

Java基础——初识Math类,基本运算符,自增自减运算符,逻辑运算符,位运算符,三元运算符

Java基础——初识Math类,基本运算符,自增自减运算符,逻辑运算符,位运算符,三元运算符初识Math类 Math.pow(2,3); //运用工具类进行次方运算基本运算符 1.算术运算符:+,-,,/,%(此前为二元运算符),++,--(一…

ENC28J60

ENC28J60ENC28J60 是在嵌入式开发、物联网、单片机联网中常见的一种芯片。 我们来从硬件、软件、应用三个角度讲清楚它。🧩 一、基本定义ENC28J60 是 Microchip(微芯科技) 公司生产的一款 独立的以太网控制器芯片(…

第七章 常见攻击事件分析--钓鱼邮件

第七章 常见攻击事件分析--钓鱼邮件 1、请分析获取黑客发送钓鱼邮件时使用的IP,flag格式: flag 将文件下来到虚拟机解压有个钓鱼邮件.eml 查阅的时候觉得这里很奇怪,这里跟其他的不大一样,这里对来源进行了base64的…

10月18日日记

1.今天放假出去吃饭 2.明天准备去图书馆 3.编写怎样的代码更有利于JIT优化?

第九章-实战篇-运维杰克

第九章-实战篇-运维杰克 1、攻击者使用的的漏洞扫描工具有哪些(两个) flag 我们首先先去 /var/log下面看一下 发现这个网站中间件是apach 逛了一圈没有发现什么东西, 但是先统计一下在日志里面哪些ip访问的数量最多,…

AntennaPod - 开源Android播客管理器

AntennaPod是一款易于使用、功能灵活的开源Android播客管理器。支持自动下载、播放控制、多平台同步等特性,提供无广告的纯净播客收听体验,让您自由管理个人播客订阅。AntennaPod - 开源Android播客管理器AntennaPod…

硬件基础知识

1. 关于串口电平和 RS232 、RS485、RS422 的引脚接线 串口常用的电平标准有如下三种:TTL电平:+5V表示1,0V表示0RS232电平:-3~-15V表示1,+3~+15V表示0RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号) 引…

第三章 权限维持-linux权限维持-隐藏

第三章 权限维持-linux权限维持-隐藏 1、黑客隐藏的隐藏的文件 完整路径md5 使用命令查看隐藏文件 find / -type f -name .*这个文件看着有点可疑临时性:将文件放在 /tmp 目录下表明这些文件可能是临时的。系统重启后…

第五章 linux实战-黑链

第五章 linux实战-黑链 1、找到黑链添加在哪个文件 flag 格式 flag 什么是黑链?在网络安全领域,黑链(Blacklink 或 Badlink)一般指那些用于 恶意目的的链接。这些链接通常不是合法或正常的网站地址,而是被攻击者利…

AI元人文:价值原语化——在创新与传承间搭建文明桥梁

AI元人文:价值原语化——在创新与传承间搭建文明桥梁 当我们深耕价值语义的原语化,实则是启动了一项宏大的文明工程:为流动的价值经验建造可传承、可演化的语言载体。这不仅是方法论的创新,更是对文明传承模式的深…

Channel小结

一:channel的一些特性 1.尽量避免使用锁来解决临界资源安全问题 2.通道的角色必须在两个及以上 3.chan,必须要作用在两个以上的goroutine 二:通道的声明点击查看代码 func main() {//声明+赋值var c chan intc = ma…

线段树历史值学习笔记

(先单开出来,后面准备合并到线段树 trick 里) (好像合并不了了) 历史和指的是线段树维护的序列 \(a\),我们再开一个序列 \(b\),每次修改 / 查询后进行 \(\forall b_i \leftarrow b_i + a_i\) 操作,\(b\) 称作 …

连续两行fastq、连续两行MD5值如何转换为每行一个fastq一个MD5格式

001、shell实现(base) [b20223040323@admin2 test]$ ls a.txt (base) [b20223040323@admin2 test]$ cat a.txt ## 测试数据 SRR5534377_1.fastq.gz SRR5534377_2.fastq.gz d27d0b0f0bb9cae5dc52dc934384699b 1139…

bridge 一般是 网络桥接模块。

bridge 一般是 网络桥接模块。bridge 一般是 网络桥接模块。 在 Linux 网络栈中,Bridge 就是用来实现 “二层转发(L2 switch)” 的:让两个网络接口互通(比如 eth0 ↔ wlan0);常用于路由器的 AP 模式;也可能是 …