对于检测同一斜线上是否有多皇后,可以将正/反对角线上下移动(即col值保持不变,row值加减),并只考虑棋盘内坐标(如下图)。最终采用回溯法求解八皇后问题,共有92种解。
main.cpp
//
// main.cpp
// Eight_queens
//
// Created by _R on 2019/4/24.
// Copyright © 2019 _R. All rights reserved.
//
#include <iostream>
#include "ChessBoard.hpp"
int main(int argc, const char * argv[]) {
ChessBoard chess = ChessBoard();
chess.putQueen(0);
cout << "Number of Solutions: " << chess.getNumSolu() << endl;
return 0;
}
ChessBoard.cpp
//
// ChessBoard.cpp
// Eight_queens
//
// Created by _R on 2019/4/24.
// Copyright © 2019 _R. All rights reserved.
//
#include "ChessBoard.hpp"
#include <iostream>
using namespace std;
ChessBoard::ChessBoard(){
sideLength = 8;
numQueens = 8;
numSolu = 0;
initializeBoard();
}
ChessBoard::ChessBoard(int sl, int nq){
sideLength = sl;
numQueens = nq;
numSolu = 0;
initializeBoard();
}
void ChessBoard::initializeBoard(){
board = new int*[sideLength];
for (int i = 0; i < sideLength; i++) {
board[i] = new int[sideLength];
}
for (int row = 0; row < sideLength; row++) {
for (int col = 0; col < sideLength; col++) {
board[row][col] = 0;
}
}
}
void ChessBoard::printBoard(){
for (int row = 0; row < sideLength; row++) {
for (int col = 0; col < sideLength; col++) {
cout << board[row][col] << " ";
}
cout << endl;
}
}
int ChessBoard::getSideLength(){
return sideLength;
}
int ChessBoard::getNumSolu(){
return numSolu;
}
int ChessBoard::getNumQueens(){
return numQueens;
}
bool ChessBoard::isGood(){
for (int row = 0; row < sideLength; row++) {
int sum = 0;
for (int col = 0; col < sideLength; col++) {
sum += board[row][col];
}
if (sum > 1) {
return false;
}
}
for (int col = 0; col < sideLength; col++) {
int sum = 0;
for (int row = 0; row < sideLength; row++) {
sum += board[row][col];
}
if (sum > 1) {
return false;
}
}
// move the diagnol up and down
for (int i = -(sideLength-2); i <= sideLength+2; i++) {
int sum = 0;
for (int j = 0; j < sideLength; j++) {
if (j+i >= 0 && j+i < sideLength) {
sum += board[j+i][j];
}
}
if (sum > 1) {
return false;
}
}
// move the back-diagnol up and down
for (int i = -(sideLength-2); i <= sideLength+2; i++) {
int sum = 0;
for (int j = 0; j < sideLength; j++) {
if ((sideLength-1-j)+i >= 0 && (sideLength-1-j)+i < sideLength) {
sum += board[(sideLength-1-j)+i][j];
}
}
if (sum > 1) {
return false;
}
}
return true;
}
void ChessBoard::putQueen(int queen){
if (queen == numQueens) {
cout << "For Solution #" << numSolu++ << ":" << endl;
printBoard();
cout << endl;
return;
}
// Each queen moves along a col
for (int row = 0; row < sideLength; row++) {
board[row][queen] = 1;
if (isGood()) {
putQueen(queen+1);
}
board[row][queen] = 0;
}
}
ChessBoard.hpp
//
// ChessBoard.hpp
// Eight_queens
//
// Created by _R on 2019/4/24.
// Copyright © 2019 _R. All rights reserved.
//
#ifndef ChessBoard_hpp
#define ChessBoard_hpp
#include <stdio.h>
using namespace std;
class ChessBoard{
public:
ChessBoard();
ChessBoard(int, int);
bool isGood();
void putQueen(int);
void printBoard();
int getSideLength();
int getNumSolu();
int getNumQueens();
private:
void initializeBoard();
int sideLength;
int numQueens;
int numSolu;
int **board;
};
#endif /* ChessBoard_hpp */