[题解]UVA1603 破坏正方形 Square Destroyer
是一道启发式搜索和位运算,剪枝的杂合题目。 要学好搜索,搜索是很重要的算法。那些很厉害的选手都是搜索打得好的。(By Instructor Li) 题目分析 首先, \(N≤5\) ,且边数是 \(2N(N+1)≤60\) 。在这样的小数据下可以位运算优化。 启发式搜索,设计估价函数 \(G(X)\) 。要求低于真实代价。下面是一种方法: 对于每一个正方形,删除它的所有边。重复这个操作知道没有正方形。操作的次数就是估价 然而,仅仅这样不足以过掉这题。还需要优化。 判断正方形 在纸上推导一下,或者直接找规律,可以得到: 如果一条横放的火柴编号为 \(X_0\) , \(X_0\) 左下方的 \(L\) 根火柴分别是:$ X_i=X + (2i-1) N + i - 1,(0<i<L)$。 那么正方形的左边界确定了,右边界的编号就是左边界加上边长。 预处理出所有的正方形,并且按照从小到大的顺序。原因后面会说 这样在DFS函数里减少了判断正方形的开销 位运算的技巧 用==unsigned long long==存储一个正方形的边的编号。 利用==&==,==|==运算符可以完成判断正方形是否存在,在一个状态上增加边等操作。具体实现方法是 #define Mark(X,K) (X=X|((Ull)1<<((K)-1))) #define Del(X,K) (X&(~((Ull)1<<((K