LeetCode 52

        这个题的意思是让我们求“n 后问题”的解法的数目,其实和上一个题基本是相似的,只需要做少量的改动就行,主要的思路如下:

1.使用 vector<string> 保存每一层的Queen的位置,然后往下一层递归,测试下一层Queen的位置,若符合要求就继续上下测试,若不符合则更换位置继续测试。

2.测试函数的编写需要注意,记得斜线上的点的测试,假设我们先将Queen置于中心上,那么该点的左右,上下,以及左上方和右下方,左下方和右上方等等都需要考虑到,不要漏掉任何一点,而且需要考虑边界问题。

3.在程序中我们应该提前检测,意思就是不要递归到最后一层才检查当前方案是否合格,我们在每一层的每个位置都需要检查是否合格,这样可以提前做出决策,这样可以大大减少递归的次数,提高程序的效率。

   下面我就给出代码:

class Solution {
public:
	int totalNQueens(int n)
	{
		int ret = 0;
		vector<string> oneSolve;
		oneSolve.clear();
		for (int i = 0; i < n; ++i)
		{
			string tmp(n, '.');
			oneSolve.push_back(tmp);
		}

		_solves(ret,oneSolve, n, 0);
		
		return ret;	
	}

	void _solves(int &ret,vector<string> oneSolve, int n, int index)
	{
		if (index == n)
		{
			++ret;
			return;
		}
		for (int i = 0; i < n; ++i)
		{
			oneSolve[index][i] = 'Q';
			if (!_testQueen(oneSolve, index + 1, n))
			{//检查当前行,提前做出决策
				oneSolve[index][i] = '.';
				continue;
			}
			_solves(ret, oneSolve, n, index + 1);
			oneSolve[index][i] = '.';
		}
	}

	bool _testQueen(vector<string>& tmp, int m, int n)
	{ // m行,n列(m可能小于n)
		int i = m - 1;
		int j = 0;
		for (; j < n; ++j)
		{
			if (tmp[i][j] == 'Q')
			{
				break;
			}
		}
		// tmp[i][j] == 'Q'
		// 检查行
		for (int k = j + 1; k < n; ++k)
		{
			if (tmp[i][k] == 'Q')
			{
				return false;
			}
		}
		//检查列
		for (int k = 0; k < i; ++k)
		{
			if (tmp[k][j] == 'Q')
			{
				return false;
			}
		}
		for (int k = i + 1; k < m; ++k)
		{
			if (tmp[k][j] == 'Q')
			{
				return false;
			}
		}
		//检查斜线上的
		//左上
		int beginx = i;
		int beginy = j;
		while (beginx > 0 && beginy > 0)
		{//
			if (tmp[--beginx][--beginy] == 'Q')
			{
				return false;
			}
		}
		//右下
		beginx = i;
		beginy = j;
		while (beginx < m - 1 && beginy < n - 1)
		{
			if (tmp[++beginx][++beginy] == 'Q')
			{
				return false;
			}
		}
		//左下
		beginx = i;
		beginy = j;
		while (beginx<m - 1 && beginy > 0)
		{
			if (tmp[++beginx][--beginy] == 'Q')
			{
				return false;
			}
		}
		//左上
		beginx = i;
		beginy = j;
		while (beginx > 0 && beginy < n - 1)
		{
			if (tmp[--beginx][++beginy] == 'Q')
			{
				return false;
			}
		}

		return true;
	}
};
    程序的结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值