LeetCode Day41 N Queens II

采用位运算方法:

row表示当前行列禁位,ld表示当前行左斜线禁位,rd表示当前行右斜线禁位。
row|ld|rd表示当前行所有禁位。其反与upperlim交限制位数。所以当前行所有可用位置表示为:

pos = upperlim & (~(row | ld | rd ));

从右往左进行方案的选择
p表示最右边的可用位置

p = pos & (~pos + 1);

占用该位置后pos=pos-p,进行下一行。此时row = row | pld = (ld | p) << 1 ,rd = (rd | p) >> 1 ,进入下一行递归。

 DFS(row|p,(ld|p)<<1,(rd|p)>>1,n,upperlim);

直到某一行没有可用位置,结束,sum+1。递归返回后,检查pos还有没有其他可行方案,这即是使用while(pos)的原因。

完整代码:

class Solution {
public:
    int totalNQueens(int n) {
        int upperlim=(1<<n)-1;
        int sum=0;
        DFS(0,0,0,sum,upperlim);
        return sum;
        
    }
    void DFS(int row,int ld,int rd,int &n,const int upperlim){
        int pos,p;
        if(row==upperlim) n++;
        else{
            pos=upperlim & (~(row | ld | rd));//找到所有可行位置,为0则已不存在可行位置,和upperlim交防止位数变化
            while(pos){
                p=pos &(~pos+1);//最右边的可行位置
                pos=pos-p;
                DFS(row|p,(ld|p)<<1,(rd|p)>>1,n,upperlim);
            }
        }
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41394379/article/details/84328642