2021年第十二届蓝桥杯C/C++ B组 I题 双向排序

试题 I:双向排序

暴力法

对于每一组操作,通过 sort 函数对原数组排序,但这样时间复杂度高,无法通过所有测试用例。

Idea

我们试着减少那些不必要的重复排序操作。通过分析可以得到以下结论:

  1. 第一次有意义的操作是降序操作(即 0 开头)

    数组一开始是按照升序排列的,所有最开始的升序操作没必要执行

  2. 对于升序操作(降序同理),当输入 (1 q) 时,只需对 [q,n] 进行操作,前面的 [1,q-1] 保持不变

  3. 连续的同类型操作合并为范围最大的那个

    例如,连续两行输入 (0 2) (0 3),可以合并为 (0 3)

  4. 每次同类型的操作都会合并,因此升序、降序操作在数组 stk 中交替出现(最开始的操作为降序)

  5. 利用结论四,对于当前输入的升序操作(降序同理),可以很容易追溯上一次的升序操作,如果当前升序操作的操作范围更大,可以证明上一次的升序操作以及它之后的降序操作是无效的

  6. 通过性质三的合并操作与性质五的追溯操作,数组 stk 中存放的升序操作(降序同理)对应的操作范围随着下标的增加单调递减

之后我们要遍历数组 stk 中存放的操作,利用结论二与结论六,数组 stk 中的每个操作都可以使一部分的数不需要进行排序操作,这样可以很方便的确定这些数最终存放的位置。

#include <iostream>

using namespace std;

const int N = 100000;
pair<int, int> stk[N]; // 存放每一步进行的操作
int ans[N]; // 存放最终的结果

int main() {
   
    int m, n, top = 0;
    cin >> n >> m
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值