2025牛客寒假算法基础集训营3补题笔记

news/2025/2/26 12:20:20/文章来源:https://www.cnblogs.com/Natural-TLP/p/18721657

比赛链接

题目难度顺序大致为:\(A、M、F、L、C、\)

\(easy\)\(A、M、F、L、C\)

太难了这场。。。E题卡了3个多小时。。。

A.智乃的博弈游戏

题意

\(n\) 个石头,两人轮流取石头。每次能取小于石头个数且与石头个数互质的数量,当某人取时只有一颗石头则获胜。问先手是否可以必胜。

思路

博弈论,思维

首先,相邻的奇数是互质的,即当 \(n\) 是奇数时,\(n - 2\) 一定和其互质。所以,奇数的局面一定可以留下2个石头给下一个人,而2个石头是必输的局面。
接着考虑当 \(n\) 是偶数时,偶数只能和奇数互质,而偶数-奇数=奇数,留奇数个石头给下一个人,那么下一个人是必胜的,理由如上。
综上所述,先手是奇数个石头必胜,偶数个石头必败。

注意开long long!

时间复杂度: \(O(1)\)

代码

点击查看代码
#include <iostream>#define ll long longusing namespace std;ll x;void solve()
{cin >> x;if (x % 2) cout << "Yes";else cout << "No";
}int main()
{int t = 1;while (t --) solve();return 0;
}

M.智乃的牛题

题意

给一个字符串,询问该字符串的字母能否组成单词 \(nowcoder\)

思路

模拟
记录每个字母次数,然后查看是否可以拼成 \(nowcoder\) 即可。

时间复杂度:\(O(n)\)

代码

点击查看代码
#include <iostream>
#include <map>using namespace std;string s;
map<char, int> mp;
string tmp = "nowcoder";void solve()
{cin >> s;for (auto i : s) mp[i] ++;for (auto i : tmp)if (i == 'o' && mp[i] == 2) continue;else if (mp[i] == 1) continue;else return void(cout << "I AK IOI");cout << "happy new year";
}int main()
{int t = 1;while (t --) solve();return 0;
}

F.智乃的捉迷藏

题意

三个人分别可以看见躲藏在面前三个位置上的人,一共有n个人躲藏,询问三人是否可以分别看见\(a、b、c\)个人。
即:\(a = s_1 + s_2 + s_3, b = s_3 + s_4 + s_5, c = s_5 + s_6 + s_1\)

思路

数学
解上面的等式:

\[a + b + c = 2 \times (s_1 + s_3 + s_5) + (s_2 + s_4 + s_6) \\ n = (s_1 + s_3 + s_5) + (s_2 + s_4 + s_6) \\ \]

\[(s_1 + s_3 + s_5) = a + b + c - n \ge 0 \\ (s_2 + s_4 + s_6) = 2n - (a + b + c) \ge 0 \]

\[n \le a + b + c \le 2n \]

时间复杂度:\(O(1)\)

代码

点击查看代码
#include <iostream>using namespace std;int n;
int a, b, c;void solve()
{cin >> n >> a >> b >> c;if (a + b + c <= 2 * n && a + b + c >= n) cout << "Yes" << '\n';else cout << "No" << '\n';
}int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t --) solve();return 0;
}

L.智乃的三角遍历

题意

给一个 \(n\) 层的三角形,询问是否可以一笔不重不漏的经过三角形上的所有边,如果可以就给出一组序列表示经过的顶点顺序。

思路

模拟

顺序不止一种,自己纸上找到一种规律然后想办法模拟下来就好了。

我的顺序是每层画完后接着画下一层

时间复杂度:\(O(n^2)\)

代码

点击查看代码
#include <iostream>
#include <vector>using namespace std;const int M = 1000 + 10;int n, m;
vector<int> g[M];
vector<int> ans;void solve()
{cin >> n;int num = 1;for (int i = 0; i <= n; i ++) {int j = i + 1;while (j --) g[i].emplace_back(num ++);}cout << "Yes" << '\n';for (int i = 0; i <= n; i ++) {for (int j = 0; j < g[i].size(); j ++) cout << g[i][j] << ' ';if (i + 1 > n) continue;for (int j = g[i + 1].size() - 2; j >= 1; j --) cout << g[i + 1][j] << ' ' << g[i][j - 1] << ' ';}for (int i = n - 1; i >= 0; i --)cout << g[i].back() << ' ';
}int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;while (t --) solve();return 0;
}

C.智乃的Notepad(Easy version)

题意

\(n\) 个单词,询问最少敲击键盘次数,在使用键盘输入过程中出现所有单词,删除键敲击也算一次。

思路

思维、贪心、字典树、\(dfs\)

存储多个单词,可以想到使用字典树来将所有单词存下。

那么问题就会转换为,遍历这颗字典树上所有节点的最小步数。

可以想到,如果是从根节点出发后再回到根节点,那么所有节点都会遍历两次。而我们并不需要回到根节点,要么从贪心角度出发,我们只需要停留在最深那个节点上即可,这样我们就不要将这最深的路径上的节点又遍历一次,答案为:所有节点个数乘二减去最深的层数。

时间复杂度:\(O(\sum|s_i| \times 26)\)

代码

点击查看代码
#include <iostream>#define ll long long
#define si(x) int(x.size())using namespace std;const int N = 1e6 + 10;
const int M = 30;int n, m;
int son[N][M], idx;
ll maxv;void insert(string s)
{int p = 0;for (int i = 0; i < si(s); i ++) {int u = s[i] - 'a';if (!son[p][u]) son[p][u] = ++ idx;p = son[p][u];}
}ll dfs(int u, ll stp)
{ll res = 1;maxv = max(maxv, stp);if (u == 0) res = 0;for (char i = 'a'; i <= 'z'; i ++) {int v = i - 'a';if (!son[u][v]) continue;ll sum = dfs(son[u][v], stp + 1);res += sum;}return res;
}void solve()
{cin >> n >> m;for (int i = 0; i < n; i ++) {string s;cin >> s;insert(s);}int l, r;cin >> l >> r;int ans = dfs(0, 0);cout << ans * 2ll - maxv;
}int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;while (t --) solve();return 0;
}

E.智乃的小球

题意

\(n\) 个小球,以及每个小球的位置 \(p_i\) 和方向 \(v_i\) ,求第 \(k\) 对完全弹性碰撞在什么时刻发生。

思路

二分、双指针

首先,假设在时刻 \(x\) 时发生了 \(k\) 对完全弹性碰撞,那么在大于 \(x\) 的时刻肯定发生了不小于 \(k\) 对的完全弹性碰撞,在小于 \(x\) 的时刻肯定没有达到 \(k\) 对完全弹性碰撞,所以时刻是具备二分性的,考虑用二分来解决。

接着,就是判断二分的时刻下发生了多少对完全弹性碰撞。
在此之前,还要知道一个点,就是两个小球完全弹性碰撞,可以看成两个小球交错而过。
假设现在向右的小球的位置为:2 4 6 8,向左的小球的位置为:3 5 7,模拟小球运动:当 2 与 3 5两个小球交错而过(即发生了两次完全弹性碰撞,后面的也如此)那么肯定的,4 在此之前一定已经和 5 相遇了一次,现在我们二分了一个时刻,可以预知向右的小球在 \(x\) 时刻后会在 \(p_i + x\) 的位置上,那么在 \([p_i, p_i + x]\) 区间内的向左的小球都会相遇一次,由此我们可以统计出所有向右的小球的碰撞总次数,再和 \(k\) 进行比较。

再计算 \([p_i, p_i + x]\) 区间内的相遇次数时,不能暴力枚举所有向右的小球,可以使用双指针去检测区间内的向左的小球的左右下标。

代码

点击查看代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>using namespace std;typedef long long ll;int n, k;
vector<int> u, v;bool check(ll x)
{ll res = 0;int l = 0, r = 0;for (auto i : u) {while (l < v.size() && v[l] < i) l ++;while (r < v.size() && v[r] <= i + x) r ++;res += r - l;}return res >= k;
}int main()
{cin >> n >> k;for (int i = 0; i < n; i ++) {int p, y;cin >> p >> y;if (y == 1) u.emplace_back(p);else  v.emplace_back(p);}sort(u.begin(), u.end());sort(v.begin(), v.end());ll l = 1, r = 1e9;while (l < r) {ll mid = (l + r) >> 1;if (check(mid)) r = mid;else l = mid + 1;}if (!check(l)) cout << "No";else cout << "Yes" << '\n' << fixed << setprecision(6) << 1.0 * l / 2;return 0;
}

J.智乃画二叉树

题意

根据题目数据画二叉树。

思路

超级大模拟,不会。。。

代码


K.智乃的逆序数

题意

构造一个序列包含若干个值域互不相交子序列,且逆序对恰好为 \(K\) 对。

思路

求逆序数的方法有:冒泡排序、归并排序、树状数组、线段树等。

先简单化考虑,因为给出的是几段大小连续且重排的序列,那么先得出逆序数最少和逆序数最多的情况。
逆序数最少的情况就是每段从小到大进行段间排序,逆序数为每段内的逆序数之和。
最大的情况就是每段从大到小进行段间排序,逆序数要根据冒泡排序算出。

我们可以从最少的逆序数的情况开始构造,如果逆序数量不够,就在段间把各自两个元素进行位置交换,知道逆序数达到 \(k\) 对。

代码

点击查看代码
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;typedef pair<int, int> PII;int n, k;
vector<PII> a;int main()
{cin >> n >> k;vector<vector<int>> b(n);for (int i = 0; i < n; i ++) {int l;cin >> l;for (int j = 0; j < l; j ++) {int x;cin >> x;b[i].emplace_back(x);}}sort(b.begin(), b.end(), [](vector<int> a, vector<int> b){return a[0] < b[0];});for (int i = 0; i < n; i ++) for (int j : b[i])a.emplace_back(i, j);int sum = 0;for (int i = 0; i < a.size(); i ++) for (int j = i + 1; j < a.size(); j ++)if (a[i] > a[j]) sum ++;if (k < sum) return cout << "No", 0;k -= sum;auto print = [&]() -> void {cout << "Yes" << '\n';for (auto it : a)cout << it.second << ' ';};if (k == 0) print();else {for (int i = 0; i < a.size() - 1; i ++)for (int j = 0; j < a.size() - 1 - i; j ++)if (a[j].first == a[j + 1].first) continue;else if (k && a[j].second < a[j + 1].second) {swap(a[j], a[j + 1]);k --;}if (k) cout << "No";else print();}return 0;
}

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

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

相关文章

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。它们有什么不同?HTTPS到底安全在哪里?HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者…

Featurewiz-Polars:一种强大且可扩展的特征选择解决方案,适用于XGBoost

前言:“Featurewiz-Polars”是一个用于特征工程的 Python 库,结合了特征选择和特征生成的功能。它基于“Polars”,这是一个高性能的 DataFrame 库,用于处理大型数据集,具有类似 Pandas 的 API 但更高效,尤其在处理大数据时。Featurewiz-Polars 专注于通过自动化方式,快速…

USACO2025FEB Gold T1 T2 题解

T3 等会补USACO2025FEB Gold 题解 赛时先看 T1,感觉很可做,推了一下发现能把问题转成在基环树上 dp。但我一下子没太想明白怎么解决“在基环树上找环”这个世纪难题,大概在一个小时 20 分钟的时候写完代码(值得一提的是这次罕见地一次就过了编译),交上去发现 WA 了大约一…

Windows10/Windows11系统快速安装杜比音效经典版教程指南

点击上方蓝字关注我 前言 在当今的数字娱乐时代,音频质量已经成为我们追求的重要部分。杜比音效,凭借其卓越的音质和沉浸式的听觉体验,成为了众多音频爱好者的首选,安装杜比音效经典版,提升电脑音频体验。无论是对于追求极致音质的音乐发烧友,还是渴望在观影和游戏时获得…

No.12 HTML5--新增标签

一、HTML5和HTMLHTML5是 HTML 最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定。 在 HTML5出现之前,我们一般采用 DIV+CSS 布局我们的页面。但是这样的布局方式不仅使我们的文档结构不够清浙,而且不利于搜索引擎爬虫对我们页面的爬取。为了解决上述缺点,HTML5新增…

ICLR 2025 | 无需训练的Token级 DiT加速方法

前言 本文分享 ICLR 2025 论文 ToCa: Accelerating Diffusion Transformers with Token-wise Feature Caching,提出的 ToCa 模型通过 token 粒度的缓存方法,实现了图像和视频生成模型上无需训练的两倍以上的加速。 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最…

Ⅱ.数据的机器级表示

章节导论: 2.1 位和数据类型 2.1.1 信息最小单位-位(0和1)(如高电压(0.9-1.1v)和低电压(0.0-0.2v)) 2.1.2 数据类型 2.2 整数 2.2.1 无符号整数 位置计数法:通过各个位置的数字不同的权重来表示一个数字 如286=2*102+8*101+6 ,在这个十进制系统中基数为10,同理,二进…

生产CPU打满问题排查

运行好好的系统,突然Prometheus告警,CUP使用率95%告警。赶紧排查一下。 一、先用top -H 命令查看占用CUP高的是哪个进程,看到PID:32518 的进程占用cup过高 二、用top -Hp 32518看看占用资源最多的线程 三、用jstack 32518 > 32518.jstack.log 命令把线程堆栈打印出来四、使…

3 2000年英语一阅读理解Text3

3 2000年英语一阅读理解Text3When a new movement in art attains a certain fashion, it is advisable to find out what its advocates are aiming at, for, however farfetched and unreasonable their principles may seem today, it is possible that in years to come th…

网盘批量分享,转存,重命名,资源监控,数据同步工具

在当今数字化时代,网盘已成为我们存储和分享文件的重要工具。然而,面对多个网盘和账号,如何高效管理这些资源成为了许多用户的难题。为此,我们推出了一款多功能网盘管理工具,旨在帮助用户轻松实现批量操作、资源监控和数据同步,提升文件管理效率。核心功能批量分享与转存…

若依开后端开发常见问题

前端填写完数据后点击提交,出现以上错误,很明显是时间格式出了问题,来看一下后端控制台:可以看出是没有统一时间格式导致的,此类情况请检查后端代码,可以在LocalDateTime类型的时间属性上增加@JsonFormat注解,效果如下:修改完成后问题解决

Beats详解

一、Beats平台介绍 1.1 Beats介绍Beats是开源数据发送者,可以将其作为代理安装在您的服务器上,以将不同类型的运营数据发送到Elasticsearch。Beats可以直接发送数据到Elasticsearch或通过Logstash发送到Elasticsearch,可以使用它来分析和转换数据。 Packetbeat,Fileb…