The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]
A straight forward approach is to check every possible solution with back-tracking.
C++ Code:
/*
* func: check_solution
* goal: check if current position can be put a queen
* @param row: row index
* @param column: column index
* @param n: total number of queens
* @param solution: current solution to check
* return: true or false
*/
bool check_solution(int row, int column, int n, const vector<string> &solution){
//Check column
for(int i = 0; i < n; ++i){
if(solution[i][column] == 'Q'){
return false;
}
}
//Check right downside
for(int i=1; row+i < n && column+i < n; ++i){
if(solution[row+i][column+i] == 'Q'){
return false;
}
}
//Check left upside
for(int i=1; row-i >= 0 && column-i >= 0; ++i){
if(solution[row-i][column-i] == 'Q'){
return false;
}
}
//Check right upside
for(int i=1; row-i >= 0 && column+i < n; ++i){
if(solution[row-i][column+i] == 'Q'){
return false;
}
}
//Check left downside
for(int i=1; row+i < n && column-i >= 0; ++i){
if(solution[row+i][column-i] == 'Q'){
return false;
}
}
return true;
}
/*
* func: solve_nqueens_helper
* goal: helper function for solve_nqueens
* @param current_row: current row to deal with
* @param n: the number of queens
* @param solution: current solution
* @param result: final result set
* return:
*/
void solve_nqueens_helper(int current_row, int n, vector<string> &solution, vector<vector<string> > &result){
if(current_row == n){
result.emplace_back(solution);
return;
}
for(int i = 0; i < n; i++){
if(check_solution(current_row, i, n, solution)){
solution[current_row][i] = 'Q';
solve_nqueens_helper(current_row+1, n, solution, result);
}
solution[current_row][i] = '.';
}
}
/*
* func: solve_nqueens
* goal: solve the problem n queens
* @param n: the number of queens
* return: all possible solutions
*/
vector<vector<string> > solve_nqueens(int n){
assert(n > 0);
vector<vector<string> > result;
vector<string> solution(n, string(n,'.'));
solve_nqueens_helper(0, n, solution, result);
return result;
}
Python Code:
# func: check if current position can be set to 'Q'
# @param solution: current solution
# @param row: row index
# @param column: column index
# @param n: dimension
# @return: True or False
def check_ok(solution, row, column, n):
#check column
i = 0
while i < n:
if i != row and solution[i][column] == 'Q':
return False
else:
i += 1
#check diagonal
i = row-1
j = column-1
while i >= 0 and j >= 0:
if solution[i][j] == 'Q':
return False
else:
i -= 1
j -= 1
i = row+1
j = column+1
while i < n and j < n:
if solution[i][j] == 'Q':
return False
else:
i += 1
j += 1
i = row+1
j = column - 1
while i < n and j >= 0:
if solution[i][j] == 'Q':
return False
else:
i += 1
j -= 1
i = row-1
j = column+1
while i >= 0 and j < n:
if solution[i][j] == 'Q':
return False
else:
i -= 1
j += 1
return True
# func: helper function for solve n-queens
# @param current_row: current row
# @param n: dimension
# @solution: current solution
# @result: final result set
def solve_nqueens_helper(current_row, n, solution, result):
if current_row == n:
result.append(solution)
return
for i in xrange(n):
solution[current_row] = '.'*i + 'Q' + '.'*(n-1-i)
if check_ok(solution, current_row, i, n):
solve_nqueens_helper(current_row+1, n, solution[:], result)
solution[current_row] = '.' * n
# func: solve the given n-queens problem
# @param n: given dimension n
# @return: all possible solution
def solve_nqueens(n):
if n <= 0:
return [[]]
solution = []
for _ in xrange(n):
solution.append('.' * n)
result = []
solve_nqueens_helper(0, n, solution, result)
return result
No comments:
Post a Comment