N皇后(回溯)

在这里插入图片描述
在这里插入图片描述
ps:皇后可以攻击同一行、同一列以及左上角、右上角、左下角、右下角这些角度方向上的任意单位。
时间复杂度:O(n!)
在这里插入图片描述

class Solution {
public:
	vector<vector<string>> solveNQueens(int n) {
		vector<vector<string>>res;
		vector<vector<int>>board(n, vector<int>(n, 0));//0表示无皇后,1表示有皇后
		DFS(n, 0, board, res);//一行一行地放皇后
		return res;
	}

	void DFS(int n, int row, vector<vector<int>>&board, vector<vector<string>>&res)
	{
		//0~n-1都填写完毕
		if (row == n)
		{
			vector<string>track = generate_track(n, board);
			res.push_back(track);
			return;
		}
		for (int col = 0; col < n; col++)
		{
			if (isUsable(board, row, col, n))
			{
				board[row][col] = 1;
				//填写下一行
				DFS(n, row + 1, board, res);
				board[row][col] = 0;//回溯
			}
		}


	}

	//board[row][col]是否可用
	bool isUsable(vector<vector<int>>&board, int row, int col, int n) {
		//检查第col列上有无皇后
		for (int i = 0; i <= row - 1; i++)
		{
			if (board[i][col] == 1)return false;
		}
		//检查左上至右下对角线有无皇后
		for (int i = col - 1; i >= 0; i--)
		{
			if (i + row - col < 0)break;
			if (board[i + row - col][i] == 1)return false;
		}
		//检查右上至左下对角线有无皇后
		for (int i = col + 1; i < n; i++) {
			if (row + col - i < 0)break;
			if (board[row + col - i][i] == 1)return false;
		}
		return true;
	}


	vector<string> generate_track(int n, vector<vector<int>>&board)
	{
		vector<string>track;
		for (int i = 0; i < n; i++)
		{
			string s = "";
			for (int j = 0; j < n; j++)
			{
				if (board[i][j] == 0)
					s += '.';
				else
					s += 'Q';
			}
			track.push_back(s);
		}
		return track;

	}

};

在这里插入图片描述
更加简单了,直接求count即可。

class Solution {
public:
	int totalNQueens(int n) {

		vector<vector<int>>board(n, vector<int>(n, 0));//0表示无皇后,1表示有皇后
		DFS(n, 0, board);//一行一行地放皇后
		return count;
	}

	void DFS(int n, int row, vector<vector<int>>&board)
	{
		//0~n-1都填写完毕
		if (row == n)
		{
			count++;
			return;
		}
		for (int col = 0; col < n; col++)
		{
			if (isUsable(board, row, col, n))
			{
				board[row][col] = 1;
				//填写下一行
				DFS(n, row + 1, board);
				board[row][col] = 0;//回溯
			}
		}


	}

	//board[row][col]是否可用
	bool isUsable(vector<vector<int>>&board, int row, int col, int n) {
		//检查第col列上有无皇后
		for (int i = 0; i <= row - 1; i++)
		{
			if (board[i][col] == 1)return false;
		}
		//检查左上至右下对角线有无皇后
		for (int i = col - 1; i >= 0; i--)
		{
			if (i + row - col < 0)break;
			if (board[i + row - col][i] == 1)return false;
		}
		//检查右上至左下对角线有无皇后
		for (int i = col + 1; i < n; i++) {
			if (row + col - i < 0)break;
			if (board[row + col - i][i] == 1)return false;
		}
		return true;
	}
private:
	int count = 0;

};

发布了212 篇原创文章 · 获赞 4 · 访问量 8800

猜你喜欢

转载自blog.csdn.net/ShenHang_/article/details/104578481