知识点:深搜,剪枝,位运算
难度:3
感觉这个题还是比别的难度为3的题要难一些,因为用到了状压搜索,我这里使用的写法是把每一行的状态当成了函数参数的写法,也就是函数里面有三个参数表示状态,每个数表示当前行的每一列当前情况下是不是可选的点,第一个是竖直,第二个是右上到左下的对角线,第三个是左上到右下的对角线,然后我们向下一层递归的时候要计算出新的参数,两个对角线分别需要用到移位运算,然后高位低位分别补1,
我这个时间效率还不是很高,1.8s,我看洛谷其它的提交基本上都是1s左右,甚至还有500ms的,说明我这个还有将近一倍的优化空间,而且我这个不能放置的点是在递归函数里面判断的,不是一开始就预处理好的
- #include
-
- using namespace std;
-
- const int N = 14;
-
- int n, ans, h[1 << N];
- string s[N];
-
- int lowbit(int x) {
- return x & -x;
- }
-
- void dfs(int k, int col, int dia1, int dia2) {
- if (k == n) {
- ans++;
- return;
- }
- int num = col & dia1 & dia2;
- for (int i = num; i; i -= lowbit(i)) {
- int t = lowbit(i);
- if (s[k][h[t]] == '.') continue;
- col -= t;
- int t1 = dia1, t2