Codeforces Round #842 (Div. 2) 题解

A 题目链接:https://codeforces.com/contest/1768/problem/A

input:

output:

题意:

给定一个整数 k ,找到一个整数 x ,使 x ! + (x − 1) ! 是 k 的倍数 ,输出这个 x ,如果找不到,输出-1.

思路:

x ! + (x − 1) ! = (x + 1) * ( x - 1) ! , 令 x + 1 = k ,即 x = k - 1

代码如下:

B 题目链接:https://codeforces.com/contest/1768/problem/B

input:

output:

题意:

给一个长度为 n 的排列 p,给定一个数 k。给定一种操作:从排列 p 中选择 k 个数,按从小到大的顺序放到排列的末尾。问最少需要多少次操作,使得排列 p 变为从小到大的排列。

思路:

思路比较简单,找到所有不需要拿出来的数,剩下的数都是需要被操作的。

如何判断哪些数不需要操作呢?通俗来讲就是直接从原排列中找到1 ,2,3……排列即可,这些有序的数不需要被操作。说的不是很明白,具体见代码。

代码如下:

C 题目链接:https://codeforces.com/contest/1768/problem/C

input:

output:

题意:

给一个长度为 n 的数组 a,试构造排列 p 和 q ,使得对于任意 1<= i <= n ,满足 max{pi,qi} == ai,如果不能构造,输出NO,否则输出YES,并输出 p 和 q。

思路:

首先讨论是否有解。

无解的情况有两种:

  1. 数组 a 中,1出现2次及以上 ,或其他某个数出现3次及以上

  1. 构造后,发现 p 和 q 某个位置不满足要求(构造方式下面细说)

如何构造呢,直接暴力构造即可。

首先对数组 a 中所有第一次出现的数,直接构造到 p 对应的位置上。

数组 a 中尚未构造的数,构造到 q 对应的位置上。

最后,对于 p 中尚未构造的位置,我们按照其对应的 q上的数从小到大的顺序,填入最小的可以填入的数(没有在p中出现过)。q 的构造方式同理。

构造后判断是否满足要求,输出即可。

代码如下(写的太长了,很不美观,大家理解一下思想即可):

D 题目链接:https://codeforces.com/contest/1768/problem/D

input:

output:

题意:

给一个长度为 n 的排列 p ,给定一种操作,可以交换两个数 。问最少需要多少次操作,使得 p 恰好有一个逆序对。

思路:

首先提出一个结论:排列 p 恰好有一个逆序对的情形,当且仅当排列 p 两个相邻的位置,元素相反,其他位置下标与元素均相等。

思路比较简单,首先,原排列 p 中,元素与下标相等的位置不用动,其他位置需要移动才能有序。随后,这些需要移动的位置,其元素与对应下表会形成若干个环。对于一个长度为 k 的环,我们将其变为有序(也就是让所有元素回到对应的位置)需要的操作次数为 k - 1次。最后,我们考虑环内时候有两个位置相邻,如果存在至少一种相邻的情况,我们可以在该环操作的最后,不去操作这两个相邻的位置,最后得到一个相反的相邻对,满足题目要求,该环的操作次数为 k - 2 次。如果不存在环内有相邻位置的情况,那么我们将所有环归位后,多花一次操作将任意两个相邻位置交换即可。

环我们用并查集处理,两个元素 find 返回值相等,即在同一个环里。

结论:有相邻位置,代价为所有环的大小-1的和-1。无相邻位置,代价为所有环的大小-1的和+1。

代码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值