Rompecabezas de n reinas
Solución matemática
La solución no es única, este método proporciona solo uno de ellos.
DFS
Utilice cuatro matrices para registrar el estado opcional de la posición. Para cada punto llenado, la fila, columna y dos líneas diagonales que causan la falla deben ser únicas, por lo que es conveniente restaurar el estado opcional en el DFS, es más conveniente que el punto de registro [fila] [col] es mejor, porque el mismo punto puede invalidarse debido a múltiples puntos.
- Línea diagonal \:
row - col = -(n-1) ~ n-1
para facilitar el procesamiento de la matriz, el conjunto se desplaza a la derecha en n-1, luegorow - col + n-1 = 0 ~ 2n-2
- Diagonal /:
row + col = 0 ~ 2n-2
Si completa la reina fila por fila, no necesita registrar si la fila es válida o no; de la misma manera, si completa columna por columna, no necesita registrar la columna.
class Solution {
public:
int N;
vector<bool> col, ddiag, udiag;
vector<string> temp;
vector<vector<string>> ans;
vector<vector<string>> solveNQueens(int n) {
N = n;
col.resize(n, 1);
ddiag.resize(2*n-1, 1);
udiag.resize(2*n-1, 1);
for(int c=0; c<n; c++) DFS(0, c);
return ans;
}
//put queen at [r][c]
void DFS(int r, int c){
//put queen
string s(N, '.');
s[c] = 'Q';
temp.emplace_back(s);
//recursion exit
if(r==N-1){
ans.emplace_back(temp);
temp.pop_back();
return;
}
//reduce options
col[c] = false;
ddiag[r-c+N-1] = false;
udiag[r+c] = false;
//check [r+1][...]
for(int i=0; i<N; i++){
if(col[i] && ddiag[r-i+N] && udiag[r+1+i]){
DFS(r+1, i);
}
}
//roll back
col[c] = true;
ddiag[r-c+N-1] = true;
udiag[r+c] = true;
temp.pop_back();
return;
}
};