蓝桥杯2021年第十二届省赛-双向排序

蓝桥杯2021年第十二届省赛真题-双向排序 - C语言网 (dotcpp.com)

题解参考:

12届蓝桥杯省赛c++b组 I题 双向排序_thejohn2020的博客-CSDN博客_蓝桥杯双向排序https://blog.csdn.net/qq_51972900/article/details/116453220代码部分见上方题解。

根据题意,0是降序,1是升序;

显而易见的是,

1.当上一步操作是【0,a】,这一步操作是【0,b】,且 a\geqslant b时,相当于b没操作,当a< b时,相当于a的操作被覆盖掉了。两个 0降序 操作,只执行 更大的数 的操作。

例如:123456789这个序列,先执行【0,6】,序列变为654321789,后执行【0,4】,序列不变;先执行【0,4】,序列变为432156789,后执行【0,6】,序列变为654321789,相当于只要执行【0,6】;

2.当上一步操作是【1,a】,这一步操作是【1,b】,且 a\geqslant b时,相当于a被覆盖,当a< b时,相当于b被覆盖。两个 1升序 操作,只执行了 更小的数 的操作。

例如:987654321这个序列,先执行【1,6】,序列变为987651234,后执行【1,4】,序列变为987123456;先执行【1,4】,序列变为987123456,后执行【1,6】,序列不变;

3.如果第一个操作是【1,y】,原本就是升序,相当于没操作。所以开头遇到1操作就扔掉它。


那么,当0和1的交换操作时应该怎么办?

先不回答上面的问题,我们先看如下的这么一个情况:

Q:现在有【1,2,3,4,5,6,7,8,9】这样的序列,你遇到了如下操作命令(从上到下执行),请输出交换后得到的序列。

(0,9)
(1,1)
(0,7)
(1,4)
(0,6)

首先观察以下这些指令,第一条指令是【0,x】,0和1的指令是交替的,以0开头的指令是排列的顺序是降序的,以1开头的指令是升序的;

之后我们一步步来执行这些指令,

操作【0,9】:987654321

操作【1,2】:912345678

操作【0,7】:965432178

操作【1,4】:965123478

操作【0,6】:965321478

最终结果是:965321478

但是在一步步执行的过程中可以看到,因为操作【0,x】中的x在变小,操作【1,y】的y在变大,所以序列中数字不断能变化的区域是在变小的紫色的区域是已经固定的部分,黑色的区域是还可以变化的部分)

那么,为什么紫色区域是已经固定的了?

前置信息:因为肯定是0操作开头的,1操作的前面肯定是0操作,所以每次到1操作时,最左边的部分肯定已经是逆序的了

先看左边那块紫色的已经被固定的部分,因为指令【1,y】中的y是不断变大的,所以 1操作 能把数字拉回来的 能力范围变小了,于是不在1的范围里面的数字(根据前置信息,这些数字肯定是逆序)就被留在了左边;

同理,指令【0,x】中的x不断变小,不在0的范围里面的数字因为0操作的前面肯定是1,所以右边那部分肯定是升序)就被留在了右边;

于是回到之前的问题,

当0和1的交换操作时应该怎么办?

——把【0,x】和【1,y】的操作命令按照先来后到的顺序x递减,y递增 ,下面是当前命令是x的情况,(y的情况同理):

如果 新来的x_{1} 比之前来的x_{0}(这里的x_{0}是x1的上方的上方,因为0和1是交替排序的) ,那么它加入,如果新来的 x_{1}比 之前来的x ,那么新来的【0,x_{1}】向上找,直到【0,x_{1}】成为第一条命令或者找到了比 x_{1} 还要大的x_{2},那么在【0,x_{2}】的下方(这里的下方是【1,y】的位置,因为0和1是交叉排序的)的下方 插入【0,x_{1}】,同时 【0,x_{1}】下方的所有指令都被覆盖掉了。

例如把下面的操作排序成上面表格里的操作序列:

1 3
1 6
0 2
1 7
0 9
1 8
1 1
0 4
1 7
0 5
1 5
0 7
1 5
1 4
0 6

假设现在已经把命令全都排好了,要如何操作已经排好了的命令呢?

【0,9】:987654321

【1,2】:912345678

【0,7】:965432178

【1,4】:965123478

【0,6】:965321478

 可以从这个例子中看到,如果当前是0操作,那么从右侧固定(从大到小还没有被固定的)数字,到【0,x】的x右边停下;如果当前是1操作,那么从左侧固定(从大到小还没有被固定的)数字,到【1,y】中y的左边停下;

如果操作命令都执行完了,中间的数字还没被填满,那么最后一条操作是0(降序),那么中间的数字从左往右填上从大到小的数字;最后一条操作是1(升序),那么从右往左填上从大到小的数字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值