题解 P7087 【[NWRRC2013]Intellectual Property】
Starlight237 · · 题解
对于两个
9\times9 数独谜题(不管是否有解)A,B ,定义A 和B 等价当且仅当A 可以通过下列操作进行若干次变换后成为B 。
- 选择两个数字
x,y ,将所有x 变成y ,所有y 变成x 。- 在
(1,2,3),(4,5,6),(7,8,9) 三个三元组中,选择两个,作为整体交换以它为下标的行。- 选择在同一个三元组中的两个数
x,y ,交换谜题的第x 行和第y 行。- 在
(1,2,3),(4,5,6),(7,8,9) 三个三元组中,选择两个,作为整体交换以它为下标的列。- 选择在同一个三元组中的两个数
x,y ,交换谜题的第x 列和第y 列。- 把
A 转置。现在给定
n(n\le20) 个数独谜题,判断它们两两是否等价。若等价,还需要输出一种变换的方法。D x y表示将两个数字交换,R a b表示整体交换三元组(3a-2,3a-1,3a),(3b-2,3b-1,3b) 对应的行,r a b表示交换两个行,同理有C a b和c a b作为列操作。F表示取转置。
下面考虑如何比较两个数独
转置操作最多会进行一次,枚举是否转置即可。
由于任意两个数字可以交换,我们只需要设计一种对数值不敏感的 Hash,比如 unsigned int128 压缩起来。若比较的时候发现两个 Hash 值不相等,那一定(在当前变换方法下)不等价,否则暴力比较两个 std::map,std::unordered_map 等 STL 结构。