2019年8月30日CF群打卡题: 803A, 803B, 803C, 803D. 附加题: 803E, 803F.
803A Maximal Binary Matrix
描述
大意是给一个n*n的矩阵, 初始全是0, 然后要求填充k个1, 并且填充完后的矩阵字典序最大(一行一行flatten之后的字典序) + 矩阵按对角线对称
思路
优先给第一行赋值, 因为要对称, 同时也给第一列赋值. 如果第一行完成后k没有用完, 那么继续第二列. 需要注意的是, 如果当前剩余的k是1, 那么无法继续对称地赋值(除了顶点都是成对的), 此时需要另起一行(给下一个顶点).
代码
1 | def do(): |
803B Distances to Zero
描述
给一个数组nums, 为每个数找离它最近(左或者右)的0的距离. BFS水题, 一开始把所有0的位置入队就行.
1 | import collections |
803C Maximal GCD
描述
给一个正整数n, 要求输出一个长度为k的严格递增数组, 这个数组满足:
- 所有元素之和是
n. - 所有元素的最大公约数
(gcd)最大.
如果找不到满足条件的数组, 返回-1.
思路
假设目标数组所有元素最大公约数是gcd, 因为元素之和是n, gcd必然也是n的约数. 从gcd最小的倍数(它本身)开始考虑, 如果能找到一个长度为k单调递增的数列之和是n那么满足条件.
所以问题转换为: 找到一个最大的gcd使得gcd + gcd*2 + gcd*3 + ... + gcd*k <= n. 如果和小于n, 我们可以调整最后一项的大小(增大最后一项, 反正不会重复). 但是如果和大于n, 因为这个和已经是我们能找到的最小的等差数列和了(对于长度为k而言), 必然这个gcd无解.
代码
1 | import math |
803D Magazine Ad
描述
结合了字符串处理和二分搜索的题. 给一个字符串ad, 和一个我们能容忍的最大行数k. 现在要给这个字符串分行, 当在容忍范围内时, 求一个最小的行宽(单行长度).
分行规则:
- 空格处可以分行
- 字符
-处可以分行. 分出的本行带有这个- - 其他情况不可以分行
思路
二分一下所有的行宽. 满足条件就继续缩小, 否则增大. 不过这个题不好写的是判断函数… 需要双指针记录当前的字符和上一个分割处的字符-或者空格.
代码
1 | def do(): |
803E Roma and Poker
描述
原题在讲故事…总结成自己的语言大概是给一个字符串s, 里面只有WDL?四种字符. W表示加1, L表示减1, D表示什么也不做, ?表示这里可以是WDL的任意一种.
初始值为0. 另一个输入值是k. 要求重建字符串s(也就是把所有不确定的?确定化), 满足最终结果是k或者-k, 并且在字符串的中间任意一处结果不能是k或者-k.
思路
用一个dp字典, dp[i]表示在i点可以收集到的所有(中间)值. 每次结合当前字符和dp[i-1]确定此处的可能值. 如果k和-k没有出现在最后一个位置, 返回NO. 否则可以反向重建(对于?,根据右边的值,和当前的值推断?代表什么).
(这个题也挺水的其实…还不如C题难)
代码
1 | import collections |
803F Coprime Subsequences
描述
给一个数组, 问这个数组里面, 有多少个序列subsequence(下标不一样就算不同序列)满足: 这个序列的所有元素互质.
思路
所有元素互质意味这些元素的gcd是1. 我们可以枚举所有的因数, 每个因数对应着很多序列. 然后在总的序列数2**n - 1(长度n的序列有2**n - 1个子序列)中减掉因数不是1的那些.
上面的方法存在重复计数的问题: 对于因数2的所有序列中, 包含了因数4的. 所以对于2的序列来说, 要减去4, 6, 8…的数量. 容斥原理.
具体操作时需要逆序, 这样对于嵌套的重复部分, 不会多次减去.
代码
1 | import math |