Codeforces Round 987 (Div. 2)题解 A~D

embedded/2025/1/31 12:09:34/
A- Penchick and Modern Monument

由于给定的数是非递增的,所以 h [ i ] ≥ h [ i + 1 ] h_[i]\geq h[i+1] h[i]h[i+1],如果 h [ i ] > h [ i + 1 ] h[i]>h[i+1] h[i]>h[i+1] 那么二者至少要改其一。因为最终要求的数是非递减的,所以最终数组内都是同一种数的方案是可行的。枚举最后会成为数组中的哪一个数即可。

void solve () {int n;cin >> n;vector <int> h(n + 1);for (int i = 1; i <= n; i++) cin >> h[i];int ans = INF;for (int i = 1; i <= n; i++) {int sum = 0;for (int j = 1; j <= n; j++) if (h[j] != h[i]) sum ++;ans = min(sum, ans);}cout << ans << endl;
}
B- Penchick and Satay Sticks

假设 1 ∼ i − 1 1\sim i-1 1i1 已经放好了,如果 p [ i ] ≠ i p[i]\neq i p[i]=i 的话,现在要把 i i i 位置放好,当且仅当 p [ i + 1 ] = i p[i+1]=i p[i+1]=i 并且 p [ i ] = i + 1 p[i]=i+1 p[i]=i+1 时才能放好。

void solve () {int n;cin >> n;vector <int> p(n + 1);for (int i = 1; i <= n; i++) cin >> p[i];for (int i = 1; i <= n; i++) {if (p[i] == i) continue;// 找到 i 在哪int pos = -1;for (int j = i + 1; j <= n; j++) {if (p[j] == i) {pos = j;break;}}if (p[i] - p[pos] == 1) {swap (p[i], p[pos]);} else {cout << "NO" << endl;return;}}cout << "YES" << endl;
}
C-Penchick and BBQ Buns

这是一道构造题,先思考一个问题,是否存在 ( x , y ) (x,y) (x,y) 使得 x , y , x + y x,y,x+y x,y,x+y 都是平方数?答案是勾股数

再思考一个问题,是否存在 ( x , y , z ) (x,y,z) (x,y,z) 使得 x , y , z , x + y , y + z , x + y + z x,y,z,x+y,y+z,x+y+z x,y,z,x+y,y+z,x+y+z 都是平方数?我打了个表发现是没有的。

回到这个问题,也就是说,最多我们用三份相同的调料包,不可能用四份及以上的调料包。

n n n 是偶数的时候,显然可以相邻地放两个相同的数。

n n n 是奇数的时候,最小的一组勾股数是 9 , 16 , 25 9,16,25 9,16,25 至少需要 n ≥ 26 n\geq26 n26 时才能出现。

n n n 是大于 26 26 26 的奇数,我们可以在 1 , 10 , 26 1,10,26 1,10,26 处放同一个数,然后再在 23 , 27 23,27 23,27 处放同一个数,剩下的数就一直相邻放即可。

n n n 是小于 26 26 26 的奇数,不存在答案。

void solve () {int n;cin >> n;if (n < 27) {if (n & 1) cout << "-1" << endl;else {for (int i = 1; i <= n; i += 2) {cout << i << ' ' << i << ' ';}cout << endl;}} else {vector <int> a(n + 1, 0);if (n & 1) {a[1] = 1;a[10] = 1;a[26] = 1;a[23] = 2;a[27] = 2;int bnt = 3;for (int i = 2; i <= n; ) {if (a[i]) {i ++;continue;}a[i] = bnt;a[i + 1] = bnt;bnt ++;i += 2;}for (int i = 28; i <= n; i += 2) {a[i] = bnt;a[i + 1] = bnt;bnt ++;}for (int i = 1; i <= n; i++) {cout << a[i] << ' ';}cout << endl;} else {for (int i = 1; i <= n; i += 2) {cout << i << ' ' << i << ' ';}cout << endl;}}
}
D-Penchick and Desert Rabbit

兔子可以往后跳到比它当前更低的树,也可以往前跳到当前比它更高的树

这预示着,操作是可逆的、互通的

设集合 A A A 是兔子在 i i i 树能跳到的所有树的集合,显然从 A A A 内的任意一棵树都一定能跳到 i i i 树。

现在的问题就是,我们怎样地遍历才能不超时、不缺漏地合并所有集合

让我们推演一下:

对于一棵最高的树 p 1 p_1 p1,它可以直接跳到它后面所有的树上,所以直接遍历即可。

然后找到次高的树 p 2 p_2 p2,需要判断是否这棵树能跳到最高的树后面,如果可以的话,那么从 p 2 ∼ p 1 p_2\sim p_1 p2p1 都可以合并。

不断重复这个过程,又因为每个数只会被合并一次,所以时间是 O ( n ) O(n) O(n) 的。

如何找到最高、次高、 ⋯ \cdots 的位置?由于值域是 1 ∼ n 1\sim n 1n,所以可以开一个 O ( n ) O(n) O(n) 的桶。

看似上面一直说合并集合,实际上我们可以发现,当前最高的树只能往右边跳,我们只要维护上一个集合的左端点,以及维护上一个集合的最小值即可。

void solve () {int n;cin >> n;vector <int> a(n + 1);vector <int> v[n + 1]; // 桶排序vector <int> ans (n + 1); // 用来计答案for (int i = 1; i <= n; i++) {cin >> a[i];v[a[i]].emplace_back(i);}int l = n + 1, minn = INF; // 最开始上个集合的左端点是 n + 1,最小值无穷大。for (int i = n; i >= 1; i--) {for (int j = v[i].size() - 1; j >= 0; j--) { // 遍历所有大小为 i 的桶if (v[i][j] >= l) continue; // 如果这个值在上个集合内部就跳过ans[v[i][j]] = i; // 首先将答案初始化为自身if (i > minn) { // 如果当前的值大于上个集合内部的最小值for (int k = v[i][j]; k < l; k++) { // 那么它能去的最大值就是上个集合的最大值ans[k] = ans[l]; // ans[l] 是上个集合内最大值,上个集合内所有数的答案都是 ans[l]minn = min(minn, a[k]); // 更新最小值}l = v[i][j]; // 更新左端点} else {int temp = INF; // 如果无法访问到上一个集合内部for (int k = v[i][j]; k < l; k++) { // 那么后续的集合肯定无法访问到上一个集合内部ans[k] = ans[v[i][j]]; // 此时新开一个集合temp = min(temp, a[k]);}minn = temp; l = v[i][j];}}}for (int i = 1; i <= n; i++) {cout << ans[i] << ' ';}cout << endl;}

http://www.ppmy.cn/embedded/158349.html

相关文章

[C语言日寄] <stdio.h> 头文件功能介绍

在C语言的世界里&#xff0c;<stdio.h> 是一个极其重要的头文件&#xff0c;它提供了标准输入输出功能&#xff0c;是C语言程序与用户交互的核心工具。今天&#xff0c;我们就来深入探讨 <stdio.h> 的功能、使用注意事项以及它的拓展应用。 功能介绍 <stdio.h…

MySQL基本架构SQL语句在数据库框架中的执行流程数据库的三范式

MySQL基本架构图&#xff1a; MySQL主要分为Server层和存储引擎层 Server层&#xff1a; 连接器&#xff1a;连接客户端&#xff0c;获取权限&#xff0c;管理连接 查询缓存&#xff08;可选&#xff09;&#xff1a;在执行查询语句之前会先到查询缓存中查看是否执行过这条语…

【Java-数据结构】Java 链表面试题下 “最后一公里”:解决复杂链表问题的致胜法宝

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 引言&#xff1a; Java链表&#xff0c;看似简单的链式结构&#xff0c;却蕴含着诸多有趣的特性与奥秘&#xff0c;等待我们去挖掘。它就像一…

Vue.js组件开发-实现对视频预览

在 Vue 中实现视频文件预览 实现步骤 创建 Vue 组件&#xff1a;构建一个 Vue 组件用于处理视频文件的选择和预览。文件选择&#xff1a;添加一个文件输入框&#xff0c;允许用户选择视频文件。读取文件&#xff1a;监听文件选择事件&#xff0c;使用 FileReader API 读取所选…

【Linux权限】—— 于虚拟殿堂,轻拨密钥启华章

欢迎来到ZyyOvO的博客✨&#xff0c;一个关于探索技术的角落&#xff0c;记录学习的点滴&#x1f4d6;&#xff0c;分享实用的技巧&#x1f6e0;️&#xff0c;偶尔还有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原创✍️&#xff0c;感谢支持❤️&#xff01;请尊重原创&#x1…

设想中的计算机语言:可执行对象的构造函数和析构函数

经典 C语言的内存管理&#xff0c;是一块一块的&#xff0c;用malloc分配内存&#xff0c;用free释放内存。 C有对象&#xff0c;一个对象是好几片内存&#xff0c;用指针连接起来&#xff0c;用构造函数和析构函数管理对象。 创意 如图&#xff0c;是一个“可执行对象”&am…

2024年数据记录

笔者注册时间超过98.06%的用户 CSDN 原力是衡量一个用户在 CSDN 的贡献和影响力的系统&#xff0c;笔者原力值超过99.99%的用户 其他年度数据

iic、spi以及uart

何为总线&#xff1f; 连接多个部件的信息传输线&#xff0c;是部件共享的传输介质 总线的作用&#xff1f; 实现数据传输&#xff0c;即模块之间的通信 总线如何分类&#xff1f; 根据总线连接的外设属于内部外设还是外部外设将总线可以分为片内总线和片外总线 可分为数…