题目描述:
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
本来我觉得会有dp解法,想了很久没想出来,就拿 N-Queens改了下,然后就AC了……都是泪……
class Solution {
public:
int count;
int N;
int totalNQueens(int n) {
N = n;
count = 0;
vector<int> rec;
solve(n, rec);
return count;
}
void solve(int n, vector<int> &rec){
if (!n){
count++;
return;
}
int i = rec.size();
for (int j = 0; j < N; j++){
int m(0);
for (m = 0; m < rec.size(); m++)
if (rec[m] == j || m + rec[m] == i + j || m - rec[m] == i - j)
break;
if (m < rec.size())
continue;
rec.push_back(j);
solve(n - 1, rec);
rec.pop_back();
}
}
};
还有个在讨论区看到的很神奇的解法记录下,后面再研究……
I found this answer on the Internet. And I spent a while to figure how it works, I put the main idea on the comment. Here it is!
And a picture to illustrate how the bits projection works.
class Solution {
public:
/* backtrace program using bit-wise operation to speed up calculation.
* 'limit' is all '1's.
* 'h' is the bits all the queens vertically projected on a row. If h==limit, then it's done, answer++.
* 'r' is the bits all the queens anti-diagonally projected on a row.
* 'l' is the bits all the queens diagonally projected on a row.
* h|r|l is all the occupied bits. Then pos = limit & (~(h|r|l)) is all the free positions.
* p = pos & (-pos) gives the right most '1'. pos -= p means we will place a queen on this bit
* represented by p.
* 'h+p' means one more queue vertically projected on next row.
* '(r+p)<<1' means one more queue anti-diagonally projected on next row. Because we are
* moving to next row and the projection is skew from right to left, we have to
* shift left one position after moved to next row.
* '(l+p)>>1' means one more queue diagonally projected on next row. Because we are
* moving to next row and the projection is skew from left to right, we have to
* shift right one position after moved to next row.
*/
int totalNQueens(int n) {
ans = 0;
limit = (1<<n) - 1;
dfs(0, 0, 0);
return ans;
}
void dfs(int h, int r, int l) {
if (h == limit) {
ans++;
return;
}
int pos = limit & (~(h|r|l));
while (pos) {
int p = pos & (-pos);
pos -= p;
dfs(h+p, (r+p)<<1, (l+p)>>1);
}
}
int ans, limit;
};