Time Limit: 0.75 s
Space limit: 6 MB
Question
N * n (n <= 10) chessboard, and find the number of solutions for placing M (M <= N * n) queens.
Solution:
Status compression + bit operation search.
First, we place them row by row from top to bottom,
DFS (line, row, L, R, K)
Line: current row number
Row: column status
L: \ upper left diagonal line status
R:/upper right diagonal line
K: number of pieces placed
There are two solutions for each row: Do not put or put a pawn.
When placing a piece, you must consider where it can be placed,
State compression (row, R, L ):
For example, when n = 4
Binary Number
1 = (0001) 2 indicates that a pawn is placed in the first position
Similarly, (1111) indicates that it is full;
Available status (POS ):
15 = (1111) indicates that all locations can be placed
1 = (0001) indicates that the first position on the right can be placed
0 = (0000) indicates that it cannot be placed again.
(Pos = ~ (L | row | r) POS obtains all the positions that can be placed in the current row (you can simulate it yourself)
P = POS &-pos in the number array to get the position of the last 1, that is, a portable position.
Status (row, L, R) | P, that is, the three statuses after the current row is placed are updated.
For example, P = 1 (0001), which is currently placed on the right;
Row = 8 (1000), left is no longer allowed.
Row = p | ROW = 9 (1001), that is, neither the right nor the Left can be placed.
L and R change when line + 1 is searched for the next row
Take the upper left diagonal line L as an Example
Initially (0000)
When one pawn is placed on the right 2, the current row (0010)
Because it is the upper left diagonal line, the next line of L becomes (0001), that is, L> 1;
Similarly, r <1.
The row column status does not need to be updated when the row changes.
Code
60 ms + 2 kb accepted
#include <cstdio>int n, sum, max, k, m;void dfs (int line , int row, int l, int r, int k) {int pos, p, i;if (line > n){ if(k == m) sum++;return;}dfs (line + 1, row, l>>1, r<<1, k);if (row != max) {pos = max & (~ (row | l | r) );while (pos != 0) {p = pos & -pos;pos = pos - p;dfs (line+1,row | p, (l | p) >> 1, (r | p) << 1, k + 1);}}}int main() {scanf ("%d %d", &n, &m);max = (1 << n) - 1;dfs (1, 0, 0, 0, 0);printf ("%d", sum);}