1 条题解
-
0
题意理解
有一个 的网格,初始全白。
可以进行若干次操作,每次操作:- 选择一个非空的行集合 和一个非空的列集合 。
- 将这些行和列的所有交点 (其中 )染黑。
限制条件:
- 每行最多只能被选一次(在任意一次操作中)。
- 每列最多只能被选一次(在任意一次操作中)。
也就是说:不同的操作,行集合不重叠,列集合也不重叠。
给定最终染色情况,问是否能由这样一系列操作得到。
问题转化
将操作看成“矩形块”染色:
选择行集 和列集 ,那么 和 的笛卡尔积就是一个 矩形区域(可能不连续的行和列构成的不连续矩形)。由于行和列都不能重复使用,所以每次操作的矩形(在行列的并集意义上)不会在行上重叠,也不会在列上重叠。
这意味着:
如果某两行 在同一个操作中被选择过,那么它们染黑的列集合是完全相同的(即 )。
如果某两列 在同一个操作中被选择过,那么它们染黑的行集合是完全相同的(即 )。因此,我们可以将网格看成一些“同质块”的组合。
更形式的理解
假设一次操作选择了 行和 列,那么这些行和列的交叉点都必须是黑色的。
由于不能重复选择行列,所以一旦某一行 属于某个 ,那么这一行中所有黑色的格子必须位于 列中,并且 列在 的所有行上必须全是黑色。因此:
如果有两行 在某一列 上都是黑的,那么这两行必然被分配到同一个操作中(因为它们共享同一列,而列不能同时出现在两个不同的操作中),并且它们在其他列上的黑色模式必须完全相同。于是我们可以这样判断:
判断步骤
-
将行按黑色列的集合分类
如果两行在某一列上都是黑的,那么它们必须属于同一类(相同的行集合 ),因此它们必须具有完全相同的黑色列集合。更精确地说:
- 令 表示行 中黑色列集合。
- 如果存在某个列 使得 和 都包含 ,那么 必须等于 。否则不合法(因为列 不能在两个不同的行集合中被选择)。
-
对称地,对列也做同样判断
如果两列在某一行上都是黑的,那么它们必须具有完全相同的黑色行集合。 -
检查交叉部分是否填满
对于一个行集合 (对应某个操作)和一个列集合 (对应同一个操作),我们要求 全部是黑的(即该矩形内部无白格)。具体来说:如果 且 ,那么格子 必须是黑的。
-
并且矩形之间不重叠
由于行列不重复,不同的行类不会有相同的列类(否则某列会被两个不同行类使用,列重复)。这意味着:
每个行类 对应唯一一个列类 (就是它们黑色列的集合),每个列类 对应唯一一个行类 (就是它们黑色行的集合)。
算法流程
- 读入 和网格 。
- 将行按它们黑色列的集合分组(用哈希或字符串表示集合)。
- 如果两行黑色列集合不同,但存在一列在两行中都是黑的 → 不合法。
- 将列按它们黑色行的集合分组。
- 如果两列黑色行集合不同,但存在一行在两列中都是黑的 → 不合法。
- 对于每个行类 和对应的列类 (由其中一行的黑色列集合确定),检查 是否全黑。
- 同时,每个行类对应的列类必须互不相同(否则同一列被两个行类使用),每个列类对应的行类必须互不相同(否则同一行被两个列类使用)。
样例解析
样例 2
..#.. ..#.. ##### ..#.. ..#..中间一行(第3行)全黑,它的黑色列集合是 。
第1,2,4,5行的黑色列集合都是 。
现在看列:第3列在行1,2,3,4,5都是黑的,所以它的黑色行集合是 。
其他列:比如第1列只在第3行是黑的,黑色行集合是 。问题:列1的黑色行集合 和列3的黑色行集合 不同,但它们在行3上都是黑的,这违反规则(列1和列3都在行3是黑的,因此它们必须在同一个列类中,即应有相同的黑色行集合,但实际不同)。
所以不合法,输出No。
实现细节
- 我们可以用
bitset或者将每行黑色列集合哈希成一个值(比如字符串"0 1 4"表示第0,1,4列是黑的)。 - 按上述规则检查冲突。
- 复杂度 或 用 bitset 优化。
总结
本题的关键是发现:
一次操作相当于选择一个行集合和一个列集合的笛卡尔积(矩形)。
由于行列不重复,不同的行类必须对应不同的列类,且一个行类中的行在所有对应的列类中的列上必须全是黑色,否则不合法。
通过行按黑色列集合分类、列按黑色行集合分类,并检查它们之间的对应关系,即可判断是否合法。
- 1
信息
- ID
- 5900
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者