【Level 2】全新的 C++ 之 ranges
You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.
ranges
C++20 引入了一个强大的新库:Ranges,提供了全新的方式来操作和处理序列。其核心在于 惰性计算
和 视图(views)
,组合一系列操作来构建管道式的数据处理流。
头文件 <ranges>
基本概念
View
是一种对序列的惰性操作,不会生成新的序列,只有在真正遍历或使用的时候,视图中的元素才会被计算、处理。
Range
是指可遍历的对象,如数组、标准库容器等。
views::filter
views::filter
用于从范围中筛选满足条件的元素。
vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用 views::filter 筛选出所有的偶数
auto even_view = vec | views::filter([](int n) { return n % 2 == 0; });
遍历 even_view
并输出,将得到
2 4 6 8 10
views::transform
views::transform
用于对序列的每个元素应用一个函数,并将返回结果映射到新的视图中。
vec = {1, 2, 3, 4, 5};
// 使用 views::transform 将每个元素乘3
auto doubled_view = vec | views::transform([](int n) { return n * 3; });
遍历并输出,得到结果
3 6 9 12 15
sort 和 for_each
ranges::sort
和 ranges::for_each
等可以直接作用于 ranges
vec = {5, 1, 9, 3, 7};
// 使用 ranges::sort 对向量进行排序
ranges::sort(vec);
// 使用 ranges::for_each 遍历输出
ranges::for_each(vec, [](int n) { cout << n << " "; });
得到输出
1 3 5 7 9
views::reverse
views::reverse
用于反转序列的顺序
vec = {1, 2, 3, 4, 5};
// 使用 views::reverse 反转序列
auto reverse_view = vec | views::reverse;
遍历输出可得
5 4 3 2 1
管道组合
可以使用 管道操作符
|
对多个视图进行组合,例如将 filter
和 transform
结合。
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 筛选偶数并翻倍
auto combined_view = vec
| views::filter([](int n) { return n % 2 == 0; })
| views::transform([](int n) { return n * 2; });
遍历得到输出
4 8 12 16 20
转化为 vector 等容器
很遗憾,C++20 没有提供直接从 views
转化为 vector
的方法,但你可以手动收集视图中的元素来构造。除了遍历添加外,你可以在 C++20 中使用 ranges::copy
和 back_inserter
,如下所示
vec = {1, 2, 3, 4, 5};
// 使用 views::transform 将元素翻倍
auto doubled_view = vec | views::transform([](int n) { return n * 2; });
// 将 view 转换为 vector
vector<int> result;
ranges::copy(doubled_view, back_inserter(result));
等到 C++23 落地时,可以使用其引入的 ranges::to
,将更加简洁
vec = {1, 2, 3, 4, 5};
// 使用 views::transform 将元素翻倍并转换为 vector
vector<int> result = ranges::to<vector>(vec | views::transform([](int n) { return n * 2; }));
Description
为了公平起见,请你来编写生成摇奖号码的程序,但你并不需要生成随机数,而是遵循主办方的奇怪规定:
- 首先,你需要从数列中筛选出所有的偶数。
- 然后,将筛选后的数值翻倍。
- 接着,跳过处理后的前
a
个元素,取出剩下的元素中的前b
个。 - 最后,将处理后的数列按降序排列,并将结果输出。
Format
Input
第一行三个整数 , , ,其中 表示原数列的长度,、 如题目描述所示。
第二行包含 个整数,表示初始号码数列的元素。
Output
共一行,摇奖结果号码,号码之间用空格分隔。
Samples
10 2 3
1 2 3 4 5 6 7 8 9 10
20 16 12
8 1 4
10 21 32 43 54 65 76 87
152 108 64
C++入门
- Status
- Done
- Rule
- IOI
- Problem
- 16
- Start at
- 2024-9-3 0:00
- End at
- 2024-11-25 8:00
- Duration
- 2000 hour(s)
- Host
- Partic.
- 112