算法第一篇:N皇后问题的回溯解法 C++实现

算法第一篇:N皇后问题的回溯解法 C++实现

题目来源

牛客网-N皇后问题

问题描述

N皇后问题是指在N∗N的棋盘上摆N个皇后
要求:任何两个皇后不同行,不同列也不再同一条斜线上
返回:一个整数N,返回N皇后的摆法数

问题思路

  本人能力有限只能想到用回溯法求解,回溯法的思想和和暴力穷举类似,但不同的是回溯法设置了中止结果,当运行到某一步发现不可行的时候就会回退一步,从而减少了开销。就像走迷宫,记录每一个岔口,当我发现某条路前面的路不通时,就返回上一个岔口选择另一条路,若这个岔口的路全部不通,就再回到前一个岔口,选择另一条路径。

  以4皇后为例子,首先将第一个皇后落在第一行第一列,剩下可放的位置只有白色区域

放置第一个皇后
  假设我们将第二个皇后放在如下图的位置,那么只剩下一块白色区域,放置了第三个皇后以后,就没有位置可以再放皇后了,于是我们回到上图,选择第二行第四列的位置进行尝试,重复这样的尝试,直到四个皇后都被放置在棋盘内,则count+1。

放置第二个皇后
  同样由于水平的限制,本人还只会利用迭代实现回溯,下面是上代码:

class Solution {
public:
    /**
     * 
     * @param n int整型 the n
     * @return int整型
     */
     //判断当前棋盘上r和c是否可以放置皇后,不需要判断行因为每次都选择下一行放置皇后
    bool canplace(vector<vector<int> > board,int r,int c){
    	// 若同一列上有皇后
        for(int i=0;i<r;i++){
            if(board[i][c]==1)
                return false;
        }
        // 若斜向下的对角线上有皇后
        for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){
            if(board[i][j]==1)
                return false;
        }
        // 若斜向上的对角线上有皇后
        for(int i=r-1,j=c+1;i>=0&&j<board.size();i--,j++){
            if(board[i][j]==1)
                return false;
        }
        return true;
    }
    // 迭代实现回溯
    void helper(vector<vector<int> > board,int row,int &res){
    	// 当所有皇后都被放置在棋盘上时
        if(row == board.size()) {res++;return ;}
        // 从第一列开始遍历能否放置皇后
        for(int i=0;i<board[0].size();i++){
            if(canplace(board,row,i)){
                board[row][i] = 1;
                helper(board,row+1,res);
                board[row][i] = 0;
            }
        }
    }
    int Nqueen(int n) {
        if(n==1)return 1;
        // 将board全部置为0
        vector<vector<int> > board(n, vector<int>(n, 0));
        int res = 0;
        helper(board,0,res);
        return res;
    }
};

  如果需要在vs里运行,需要在前面加上

#include <iostream>
#include <vector>
using namespace std;

  以及main函数调用

int main() {
	int n;
	cin >> n;
	Solution s;
	cout << s.Nqueen(n) << endl;
	return 0;
}

运行结果

运行时间:30ms
超过52.49%用C++提交的代码
占用内存:404KB
超过47.41%用C++提交的代码

总结

  第一篇算法博客到此为止,希望以后一定要坚持。
  除此之外还有些话想说,很惭愧读到了研才开通自己的技术博客,本科的时候只想着期末复习一下考个高分,拿着好看点的成绩单申请个英国硕士快点读完回国考公,后来发现这条路不太好走。可惜了大学四年蹉跎没好好学习技术,均分考得高也没什么用,知识都还给老师了,现在找工作要全部自己重新拾起也挺不容易的,希望为时未晚,春招能有一个满意的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值