蓝桥杯 区间排序
题目描述
小杨有一个包含 n 个正整数的序列 a。
小杨计划对序列进行多次升序排序,每次升序排序小杨会选择一个区间 [l,r](l≤r)并对区间内所有数字,即进行升序 al,al+1,…ar 排序。每次升序排序会在上一次升序排序的结果上进行。
小杨想请你计算出多次升序排序后的序列。
输入格式
第一行包含一个正整数 n,含义如题面所示。
第二行包含 n 个正整数 a1,a2,…an,代表序列 a。
第三行包含一个正整数 q,代表排序次数。
之后 q 行,每行包含两个正整数 l,r,代表将区间 [li,ri] 内所有数字进行升序排序。输出格式
输出一行包含 n 个正整数,代表多次升序排序后的序列。
输入输出样例
输入 #1复制
5 3 4 5 2 1 3 4 5 3 4 1 3输出 #1复制
1 3 4 5 2说明/提示
样例 1 解释
- 第一次升序排序后,序列为 [3,4,5,1,2];
- 第二次升序排序后,序列为 [3,4,1,5,2];
- 第三次升序排序后,序列为 [1,3,4,5,2];
数据规模与约定
对于全部的测试数据,保证 1≤n,ai,q≤100,1≤li≤ri≤n。
注意点:
C++中,
sort
函数的第二个参数(即结束迭代器)指向的是排序区间的末尾的下一个位置(即“尾后迭代器”)。因此,为了正确地对区间[l, r]
进行排序,我们需要将r
加1,使得a.begin() + r + 1
指向区间[l, r]
的最后一个元素的下一个位置。详细解释
sort
函数的参数:
sort(first, last)
会对区间[first, last)
进行排序,即包括first
,但不包括last
。- 因此,如果我们想要排序
[l, r]
(包括l
和r
),last
应该指向r + 1
。示例:
- 假设
a = {3, 4, 5, 2, 1}
,l = 3
,r = 4
(1-based索引)。- 转换为0-based索引后,
l = 2
,r = 3
。- 要排序
a[2]
和a[3]
(即5
和2
),sort(a.begin() + 2, a.begin() + 4)
会对[a[2], a[3]]
进行排序。- 如果不加1,
sort(a.begin() + 2, a.begin() + 3)
只会排序a[2]
(即5
),而不会包括a[3]
(即2
)。数学表示:
[l, r]
包含r - l + 1
个元素。sort(a.begin() + l, a.begin() + r + 1)
会正确排序这r - l + 1
个元素。关键点
-
sort
的区间是左闭右开的:[first, last)
。-
r + 1
是为了包含r
:确保last
指向区间[l, r]
的最后一个元素的下一个位置。
sort
的参数:
- 原代码:
sort(a.begin() + l, a.begin() + r + 1);
(错误,因为a
不是vector
)- 修正后:
sort(a + l, a + r + 1);
(正确,a
是数组,直接用指针操作)输出格式:
- 原代码:
cout << a[i]<<" ";
(多了一个空格)- 修正后:
cout << a[i] << " ";
(规范写法)
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int q;
cin >> q;
while (q--) {
int l, r;
cin >> l >> r;
// 转换为0-based索引
l--;
r--;
// 对区间 [l, r] 进行升序排序
sort(a.begin() + l, a.begin() + r + 1);
}
// 输出结果
for (int i = 0; i < n; i++) {
// if (i != 0) cout << " ";
cout << a[i]<<" ";
}
cout << endl;
return 0;
}