LeetCode Day41 N Queens II
阿新 • • 發佈:2018-12-03
採用位運算方法:
row表示當前行列禁位,ld表示當前行左斜線禁位,rd表示當前行右斜線禁位。
row|ld|rd表示當前行所有禁位。其反與upperlim交限制位數。所以當前行所有可用位置表示為:
pos = upperlim & (~(row | ld | rd ));
從右往左進行方案的選擇
p表示最右邊的可用位置
p = pos & (~pos + 1);
佔用該位置後pos=pos-p
,進行下一行。此時row = row | p
,ld = (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);
}
}
}
};