N皇后问题
- N皇后问题研究的是如何将N个皇后放置在N * N的棋盘上,并且使皇后彼此不能相互攻击。(皇后可以直走,横走,斜走)
- 这里使用DFS来解决这道问题,用递归搜索所有的可能性,把符合要求的解存放在数组queenPos中,这个数组下标代表行数,对应的值代表列数。如queenPos[0]值为1,就代表皇后摆放在(0,1)这个位置。
#include<iostream>
#include<cmath>
using namespace std;
int N;
int queenPos[100];//用来存放算好的皇后位置。最左上角是(0,0),下标是行数,值是列数
void NQueen(int k) { //假设第0行到第k-1行都已经摆好的情况下,再来选择摆放k行及其后面的皇后
int i;
if (k == N) {//N个皇后摆好后输出
for (i = 0; i < N; i++)
cout << queenPos[i] + 1 << " ";
cout << endl;
return;
}
for (i = 0; i < N; i++) {//这里的i是尝试搜索答案的列数,下面的j是queenPos里的行数,k是当前的行数
int j;
for (j = 0; j < k; j++) {//和已经摆好的k个皇后的位置比较,看是否冲突
if (queenPos[j] == i || abs(queenPos[j] - i) == abs(k - j)) {//判断斜线是否重合,如果行数差等于列数差就重合
break;//冲突,测试下一个位置
}
}
if (j == k) {//执行到这里就证明,i列的位置,并没有与queenPos里的位置相冲突
queenPos[k] = i;//将第k个皇后摆在位置i(列)
NQueen(k + 1);
}
}//for(i=0;i<N;i++)
}
int main() {
cin >> N;
NQueen(0);
return 0;
}
因为在第一个for循环中,是试探摆放第一行的位置,所以当这种摆法可行时,就会输出一种方案,所以可以输出多种方案。(代码来自MOOC 郭炜老师 程序设计与算法(二))
更新:在leetcode上做了N皇后问题Ⅰ和Ⅱ
问题Ⅰ
class Solution {
void NQueen(int k,int *queenPos,vector<vector<string>> &v,int n) {
if (k == n) {//当一种结果算出后,把答案压入向量中
vector<string> vs;
string str;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (queenPos[i] == j)str+="Q";
else str+=".";
}
vs.push_back(str);
str="";
}
v.push_back(vs);
}
int i;
for (i = 0; i < n; i++) {//k是当前的行数,i是尝试的列数,j是检测的行数。
int j;
for (j = 0; j < k; j++) {
if (queenPos[j] == i || abs(queenPos[j] - i) == abs(k - j))
break;
}
if (k == j) {
queenPos[k] = i;
NQueen(k + 1,queenPos, v, n);
}
}
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> v;
int queenPos[100] = {0};
NQueen(0,queenPos,v, n);
return v;
}
};
这个要注意什么时候压入向量里,格式不对的话输出就不对
问题Ⅱ
class Solution {
void NQueen(int k,int *queenPos,int &count,int n) {
if (k == n) {
count++;
return;
}
int i;
for (i = 0; i < n; i++) {//k是当前的行数,i是尝试的列数,j是检测的行数。
int j;
for (j = 0; j < k; j++) {
if (queenPos[j] == i || abs(queenPos[j] - i) == abs(k - j))
break;
}
if (k == j) {
queenPos[k] = i;
NQueen(k + 1,queenPos, count, n);
}
}
}
public:
int totalNQueens(int n) {
int v=0;
int queenPos[100] = {0};
NQueen(0,queenPos,v, n);
return v;
}
};