构造题做题记录
构造题一个很显著的特点就是高自由度,也就是说一道题的构造方式可能有很多种,但是会有一种较为简单的构造方式满足题意。看起来是放宽了要求,让题目变的简单了,但很多时候,正是这种高自由度导致题目没有明确思路而无从下手。
构造题另一个特点就是形式灵活,变化多样。并不存在一个通用解法或套路可以解决所有构造题,甚至很难找出解题思路的共性。
以上内容来自 oi-wiki。
最近发现随便一个 CF *2000 的构造我都不会做了,所以开了个坑。
关于难度
\(\color{gray}\bigstar\) 可以秒杀的题。
\(\color{green}\bigstar\) 思考一会儿后可以秒的题。
\(\color{blue}\bigstar\) 需要较长时间思考的题。
\(\color{Gold}\bigstar\) 看题解、稍加指点就会做的题。
\(\color{red}\bigstar\) 看题解后需要较长时间消化,甚至现在都没有完全理解的题。
CF1276C *2300 \(\color{green}\bigstar\)
我们称一个矩阵是美丽的,当且仅当该这矩阵中不存在两个相同的数在同一列或在同一行。
给定 \(n\) 个数,要求你选出尽量多的数,使它们能够组成一个美丽的矩形。
构造方案,\(n\le 4\times 10^5\)。
考虑如果只填一种数,咋填可以满足条件。
显然斜着填是一种很好的方式。
考虑斜着一个数最多能放多少个,于矩形的宽有关。
矩形的宽 \(\le \sqrt{n}\) ,所以可以枚举。
假设当前宽为 \(m\) ,那么最多能放 \(\sum min(cnt_i,m)\) 个数,\(cnt_i\) 表示 \(i\) 的出现次数。
找个最大值,现在考虑构造方案。
一个简单的想法是这样构造:
相同的数相邻放,这样很优,而且一定可以填满。
但这样会有一个问题了,如果有一个数出现 \(m\) 次,那么会出现这种情况:
这样会有一列有两个相同的数。
咋处理呢?很简单,把出现 \(m\) 次的数全部放最前面,这样就不会有一个数字被拆到两条斜线上的情况
CF1552E *2300 \(\color{Gold}\bigstar\)
\(n\times k\) 个格子,编号从 \(1\) 到 \(n \times k\),染成 \(n\) 种颜色,每种颜色恰好 \(k\) 个。
构造 \(n\) 个区间,第 \(i\) 个区间 \([a_i, b_i]\)
满足 \(1 \le a_i < b_i \le n \times k\).
第 \(a_i\) 个和第 \(b_i\) 个格子的颜色都是 \(i\)。
每个格子被包含不超过 \(\lceil \frac{n}{k-1} \rceil\) 次。
\(n,k\le 100\)
考虑每个格子不超过 \(\lceil \frac{n}{k-1} \rceil\),那么把 \(k-1\) 中颜色变成一组,那么相当于对于每组来说每个格子最多覆盖一次。
考虑贪心,如果一个格子可以与前面匹配,那么必然匹配,这样对后面的贡献最优,然后把已经被覆盖的格子向后跳即可。
ARC138D *2083 \(\color{gold}\bigstar\)
已知 \(n\) 和 \(k\) ,求构造一个 \(0...2^n-1\) 的排列,使得相邻两数异或值的二进制位上有 \(k\) 个 \(1\)。
\(n,k\le 18\)。
这题评分不应该这么低啊。有原题,所以场上大部分通过此题的都是中国人。。
其实还是很好的一个题,考虑 \(k=1\) 时是个经典的东西 格雷码,可以直接构造。
如果 \(k\) 是偶数或者 \(k>n\) 显然无解。
考虑格雷码每次操作使得每两个相邻的值相差一位,那么只需要把这个一位换成 \(k\) 位二进制数即可,一个思路是把所有二进制位上有 \(k\) 个 \(1\) 的数拿出来。
由于需要构造出 \(0..2^n-1\),可以发现线性基中的数恰好可以凑出所有的数。
所以先跑一边格雷码,然后把线性基中的数记录一下,格雷码上一个 \(1\) 就表示异或上线性基中第几个数即可。