Codeforces Round #739 (Div. 3)

20210907。网址:https://codeforces.com/contest/1560。

……(叹)。

A

不希望出现带“3”的数和3的倍数,把剩下的数从小到大排,问第k个是多少。数据范围很小,因此是大水题。

B

偶数个人围成圈,按顺时针给每个人编号,不知道总共多少人。问题是,如果知道a和b面对面,那么c和谁面对面。简单的讨论,注意围不成圈的情况(如1和3面对面,问99对面是谁)。

C

用一种方式(详见题目,很容易的)把正整数从小到大排在无穷大的正方形棋盘上。给一个正整数k,问它在棋盘上的位置。也是简单讨论。

D

对一个正整数n,我们可以做两种操作,一种是随便擦掉一个数位(如1462 -> 162),另一种是在数结尾追加一位。我们想通过这样的操作把n变成2的幂,问最少操作多少次。注意最后结果不能是0打头的,也就是说需要特意把0擦掉。

用贪心的做法:我们想把n变成m,用两个指针i、j记录我们考察到的n、m的位置。

  • 如果n的第i位和m的第j位匹配,不用做任何操作,继续往后考虑,++i ++j。
  • 如果n的第i位和m的第j位没有匹配,那就擦掉n的第i位去看i+1位,这里的擦掉是一次操作,因此++i的同时++操作次数。
  • 如果n遍历完了而m没有遍历完,则往n后面追加【m没有被匹配上的这些数】,每一个追加都是一次操作,记录操作次数。

遍历所有m(也就是2的幂),得到最少操作次数。

编程细节:一开始我认为,n最大是1e9,考虑到2^10=1024差不多1e3,我们算到2^30就可以了,也就是只有31个m用来遍历。后来发现需要开long long,好像考察了64个2的幂(0-63)才过。

E

通过轮流做这样的操作,可以从一个字符串s生成字符串t:把s追加到t上(t=t+s);随便从s中选一个字母,然后删去这个字母的所有出现(如science删掉e变成scinc)。一开始t是空串。

给我们字符串t,让我们反推字符串s,以及选字母来删掉的顺序。(如果有多个答案,输出一个就可以。)

选字母删掉的顺序比较简单:删到最后时,只剩下一个字母了,因此t的最后一个字母就是我们最后删掉的字母。然后把t中那个字母的所有出现都划掉,划完后t的最后一个字母就是我们倒数第二个删掉的字母,然后再划掉……这样得到。

然后我们通过粗暴的遍历寻找s。因为生成t的第一步就是追加原本的s,所以s是t的前缀。然后,一个字母在t中出现的次数肯定是在s中出现次数的倍数,这一条能排除不少前缀。(还有排除前缀的方法,比如【一个字母在t中出现的次数/在s中出现的次数】就是这个字母被删掉前t.append(s)的次数,可以和【选字母删掉的顺序】做对照)最后,对于看起来符合要求的前缀,我们把它当作s反推t,如果反推结果和给出的t一样,就ok了。如果遍历所有前缀也没有找到答案,输出-1。

F

我们定义k漂亮数:如果一个数的十进制形式只包括不超过k个不同的数,它是一个k漂亮数。比如说,12121212是2漂亮数;99999是1漂亮数,同时也是2、3、4、5、…漂亮数。

给我们一个正整数n,再给一个k,让我们找最小的【大于n的k漂亮数】。

出于这样一个简单的考虑:如果要把原数某些位变大,使其成为一个k漂亮数的话,因为希望得到的k漂亮数尽量小,因此变大的数位越靠后越好。

做法:

  • 首先寻找原数的一个前缀,这个前缀包含的不同的数不超过k个(也就是说前缀是k漂亮的),寻找这样一个尽量长的前缀。比如说,12133522的最长3漂亮前缀是12133。可以用map来维护<数位,出现次数>的映射关系,用mp.size()得到不同的数的个数。
  • 好的我们找到了这样的前缀,设它的下标范围为[0,pos]。我们考察pos+1位置的数,试图在【前缀已经有的数】的集合里面找一个大于【pos+1位置的数】的最小的数,然后我们把pos+1位置换成这个数,pos+2直到结尾换成【前缀已经有的数】集合里最小的数,就得到了。
  • 但是有一个问题:如果【前缀已经有的数】这个集合里面没有比【pos+1位置的数】大的数怎么办,比如【pos+1位置的数】是9?emm,这证明我们考察的这个前缀没有前途,没法通过改【pos+1位置的数】得到答案。于是我们退一步,考虑[0,pos-1]前缀,同时维护<数位,出现次数>的映射,把pos位置的数去掉。
  • 好的我们退了一步,仍然记现在考虑的前缀是[0,pos]。如果退一步之后的前缀【不同数个数<k】,那么可以把【pos+1位置的数】换成原来这个数+1,然后更新<数位,出现次数>映射,记上这个+1后的数。(注意如果【pos+1位置的数】是9,那么没法+1,仍然需要退一步,所以只要是9就需要退一步。)如果此时仍然【不同数个数<k】,我们就把【pos+2直到结尾】的所有数换成0,因为被用掉的数不足k个,再加一个0也没关系。如果此时【不同数个数=k】了,我们就把【pos+2直到结尾】的所有数换成【前缀已有的数】集合里面最小的数(事实上这个数也可能是0)。
  • 一个编程细节:如果我们一退再退,直到前缀为空,那该怎么办呢?比如说1112345,k=1,一开始得到的【最长k漂亮前缀】是111,然而2没法换(只有1一个数被占用,没有比2大的),所以退一步变成11,但是1也没法换(也没有比1大的,1不比自己大),……,就得到空前缀了。我们用[0,-1]来表示空前缀,pos=-1。此时【不同数个数=0】了(前缀是空的啊),所以有【不同数个数<k】,然后可以把【pos+1位置的数】(也就是0位置的数,第一个数)换成原数+1,然后按照上一段的流程继续做就可以,最后得到2222222。所以说,上一段的流程也适用于pos=-1的情况。

此时,我们已经顺完了整个逻辑。逻辑就是,

  • 把我们考察的前缀初始化为最长的k漂亮前缀,对前缀进行迭代:
  • 先考察【前缀后面紧跟的那个数】是不是9,如果是则考察更短的前缀;
  • 考察有没有【不同数个数<k】,有的话特殊处理;
  • 如果【不同数个数=k】,试图增大前缀后面紧跟的那个数;
  • 如果不能通过增大该数得到答案,就退一步考察更短的前缀,直到前缀为空,前缀为空时一定能做出来。

刷题记录:Codeforces Round #739 (Div. 3)的更多相关文章

  1. 【做题】Codeforces Round #436 (Div. 2) F. Cities Excursions——图论+dfs

    题意:给你一个有向图,多次询问从一个点到另一个点字典序最小的路径上第k个点. 考虑枚举每一个点作为汇点(记为i),计算出其他所有点到i的字典序最小的路径.(当然,枚举源点也是可行的) 首先,我们建一张 ...

  2. 【做题】Codeforces Round #429 (Div. 2) E. On the Bench——组合问题+dp

    题目大意是给你n个数,求相邻两数相乘不是完全平方数的排列数. 一开始看到这题的时候,本人便想给相乘为完全平方数的数对建边,然后就写萎了... 后来通过集体智慧发现这个重要性质:对于自然数a,b,c,若 ...

  3. Codeforces Round #739 (Div. 3)

    A. Dislike of Threes 简单的水题,预处理即可 AC_CODE #include <bits/stdc++.h> using namespace std; templat ...

  4. 【做题】Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆环

    前言:结论题似乎是我的硬伤…… 题意是给你一个无向图,已知连接到每一个点的边的权值和(为整数,且属于区间[-n,n]),需要求出每条边权值的一个合法解(都要是在区间[-2*n^2,2*n^2]内的整数 ...

  5. 套题:Codeforces Round #194 (Div. 1) (2/5)

    A. Secrets http://www.cnblogs.com/qscqesze/p/4528529.html B. Chips http://www.cnblogs.com/qscqesze/p ...

  6. DP刷题记录

    目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...

  7. 刷题记录:Codeforces Round #724 (Div. 2)

    Codeforces Round #724 (Div. 2) 20210713.网址:https://codeforces.com/contest/1536. div2明显比div3难多了啊-只做了前 ...

  8. 刷题记录:Codeforces Round #734 (Div. 3)

    Codeforces Round #734 (Div. 3) 20210920.网址:https://codeforces.com/contest/1551. 编程细节:下标定义不要一会[1,n]一会 ...

  9. 刷题记录:Codeforces Round #725 (Div. 3)

    Codeforces Round #725 (Div. 3) 20210704.网址:https://codeforces.com/contest/1538. 感觉这个比上一个要难. A 有一个n个数 ...

随机推荐

  1. Node.js安装与环境配置

    废话不多少直接上干货.坐车扶稳, 当然你要知道Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.其次Node.js是一个事件驱动I/O服务端JavaScript环境, ...

  2. 【Srping】事务的执行原理(一)

    在使用事务的时候需要添加@EnableTransactionManagement注解来开启事务,那么就从@EnableTransactionManagement入手查看一下事务的执行原理. @Enab ...

  3. Django——表单

    一.前言 看了下教程,以为表单很简单呢,结果搞了一两个钟才弄懂,哈哈哈,所以说不要小瞧每一件事. 先说明下HTTP请求: HTTP协议以"请求-回复"的方式工作.客户发送请求时,可 ...

  4. JS:相等判断

    1.=  赋值运算符 错误写法:a+b = c; 2.== :=== ==判断值是否相等 例: var a = 2; var b = 3; var c = a+b; var d = "2&q ...

  5. JavaScript产生随机颜色

    //获取rgb类型的颜色 IE7不支持 function randomColor(){ var r = Math.floor(Math.random()*256); var g = Math.floo ...

  6. Canal实现MySQL协议

    目录 代码流程 执行dump前 执行dump 在学习Canal的时候很好奇Canal是如何模拟成MySql Slave来接收数据的 MySql Slave会向主库发送dump协议来接收bin-log数 ...

  7. Linux YUM制作自己的yum repository

    Linux YUM制作自己的yum repository 配置步骤: 1.通过网络发布自己的package目录 2.创建本地repository 3.配置自己的yum源 操作实现: 1 安装creat ...

  8. 使用dnSpy对无源码EXE或DLL进行反编译并且修改

    背景 总有一些特殊情况,我们没有源码,但是某个C#程序集dll或者可执行程序exe影响到我们代码的正常运行,我们希望得到源码,能改掉或者修改某些bug,但是苦于没有源码,这个时候可以用dnspy进行源 ...

  9. C语言中限定符的作用

    C语言中常用的一般包括const.static.extern.register和volatile这几个.这些是C语言标准中规定的关键词,所有的编译器都必须支持这些关键词,它们的作用如下: 1.cons ...

  10. 常用类-Instant、DateTimeFormatter类的使用

    一.Instant 我们所处的时间点是在东八区,Java中Instant所计算出来的时间是按本初子午线的时间来算的,与我们的时间相差8个小时,也就是说当我的北京时间是上午九点时,本初子午线的时间是凌晨 ...