N皇后问题 DFS C++

N皇后问题

  • N皇后问题研究的是如何将N个皇后放置在N * N的棋盘上,并且使皇后彼此不能相互攻击。(皇后可以直走,横走,斜走)

《N皇后问题 DFS C++》

  • 这里使用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;
    }
};
    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/qq_41697164/article/details/88383127
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞