[POJ 3131]

Cubic Eight-Puzzle

双向广搜

题意:有9个格子,其中8个格子有立方体。立方体相对的两面颜色相同,分别为红、白、蓝色。若某立方体相邻格为空,则该立方体可以向该方向滚动。给定初始状态,问最少滚动多少次(不大于30),可以使各盘格为指定的颜色。

类似这种搜索题,最关键的还是状态的表达。立方体的姿态可以由顶面和正面的颜色来确定,共有6种。有9个格子,考虑使用每个格子3bit,那么搜索空间的规模就是2^(3*9),大概是1亿。接下来,考虑如何判重。如果使用一个位来表示一个状态,总共需要的内存大小为2^24bytes,也就16MB,是可行的。直接开一个char c[1<<24],连hash都省了。由此,可以保证所有的操作全部为位运算。 接下来考虑搜索的形式,一般来说双向广搜,两边的深度限制相同时可以最大化降低复杂度,但该题反向搜索时起始状态较多(256个状态),层数不深时规模已经很大。因此,正向搜索深度设为20,反向为10。正向搜索完后如果找到解,则直接输出,否则才执行反向搜索。

虽然没有剪枝,但是内存全部静态分配并且大量使用位运算,程序非常的快(久违的刷到了第一)。