首页 > 编程语言 >算法学习Day30 n皇后

算法学习Day30 n皇后

时间:2024-01-18 18:00:32浏览次数:34  
标签:return int chessboard Day30 算法 皇后 col row

Day30n皇后

By HQWQF 2024/01/16

笔记


51. N皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

示例 1:

输入: n = 4输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释: 如上图所示,4 皇后问题存在两个不同的解法。

回溯法

回溯法解决N皇后问题需要把握一句话:棋盘的宽度是for循环的长度,棋盘的高度是递归的深度。

我们先在棋盘的第一行放置一个皇后,然后在下一行放皇后,如果此时布局合法就往下一行放,否则改变第二行的皇后位置,如果都不行就回溯到第一行换一个位置摆。合法地放够4行后把布局加入解集。

对于检测棋盘是否合法的函数,我们只需要检测当前最新放下的皇后的位置的同列是否有皇后(检测到当前行为止),以及左上对角方向和右上对角方向是否有。

class Solution {
private:
vector<vector<string>> result;
// n 为输入的棋盘大小
// row 是当前递归到棋盘的第几行了
void backtracking(int n, int row, vector<string>& chessboard) {
    if (row == n) {
        result.push_back(chessboard);
        return;
    }
    for (int col = 0; col < n; col++) {
        if (isValid(row, col, chessboard, n)) { // 验证合法就可以放
            chessboard[row][col] = 'Q'; // 放置皇后
            backtracking(n, row + 1, chessboard);
            chessboard[row][col] = '.'; // 回溯,撤销皇后
        }
    }
}
bool isValid(int row, int col, vector<string>& chessboard, int n) {
    // 检查列
    for (int i = 0; i < row; i++) { // 这是一个剪枝
        if (chessboard[i][col] == 'Q') {
            return false;
        }
    }
    // 检查 45度角是否有皇后
    for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    // 检查 135度角是否有皇后
    for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    return true;
}
public:
    vector<vector<string>> solveNQueens(int n) {
        result.clear();
        std::vector<std::string> chessboard(n, std::string(n, '.'));
        backtracking(n, 0, chessboard);
        return result;
    }
};

标签:return,int,chessboard,Day30,算法,皇后,col,row
From: https://www.cnblogs.com/HQWQF/p/17973107

相关文章

  • 贪心算法题目2-力扣860
    在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。注意,一开始你手头没有任......
  • 贪心算法-题目3力扣53
    给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1]的和最大,为 6。子数组 是数组中的一个连续部分。解题思路:从投......
  • 玩玩算法题——Episode 3
    Leetcode2171.拿出最少数目的魔法豆(2024-1-18每日一题)StarRating:4.03提示给定一个正整数数组beans,其中每个整数表示一个袋子里装的魔法豆的数目。请你从每个袋子中拿出一些豆子(也可以不拿出),使得剩下的非空袋子中(即至少还有一颗魔法豆的袋子)魔法豆的数目相等。一旦把魔......
  • java实现正态分布算法文心一言
    实现正态分布算法文心一言1.了解正态分布在开始实现正态分布算法之前,我们先来了解一下正态分布是什么。正态分布也被称为高斯分布,是一种常见的连续概率分布。它的概率密度函数可以用一个钟形曲线来表示,曲线的中心对应着均值,曲线的宽度对应着标准差。2.实现流程我们要实现的是......
  • 《算法竞赛》07 组合数学
    二项式定理\((a+b)^n=\sum_{i=0}^n\binomnia^ib^{n-i}\)。杨辉三角每个数对应一个组合数。卢卡斯定理\(m\)为质数时\(\binomnm\bmodp=\binom{n\bmodp}{m\bmodp}\cdot\binom{\lfloor\fracnp\rfloor}{\lfloor\fracmp\rfloor}\bmodp\)。有时候结合递归,对\(\binom{......
  • 用余弦相似度修正评分的协同过滤推荐算法
    前言今天读的这篇论文是一篇于2020年6月份发表在计算机工程与科学(ComputerEngineering&Science)上的一篇论文。论文采用评分矩阵的多种维度进行相似度比较以修正不合理评分,再用修正后的评分进行协同过滤推荐。利用MovieLens和BookCrossing数据库进行实验,结果表明:带修正评分......
  • 玩玩算法题——Episode 2
    Leetcode每日一题:最大字符串匹配数目题干如下:给你一个下标从0开始的数组words,数组中包含互不相同的字符串。如果字符串words[i]与字符串words[j]满足以下条件,我们称它们可以匹配:字符串words[i]等于words[j]的反转字符串。0<=i<j<words.length请你返回数组......
  • 贪心算法-题目1力扣455(简单题)
    力扣455,给小朋友发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j]>=g[i],我们可以将这个饼干 j 分配......
  • 算法—差分
    1.一维差分(实质:前缀和的逆运算)给区间[l,r]中的每个数加上c:B[l]+=c,B[r+1]-=c上述操作可以免去构造一个新数组,可以直接给差分赋值2.二维差分给以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵中的所有元素加上C:S[x1,y1]+=c,S[x2+1,y1]-=c,S[x1,y2+1]-=c,......
  • 2024/1/17 算法笔记
    1.欧拉质数筛功能是给一个整数n查找小于等于n的所有质数。最后使用的是prime【i】//功能:查找n内第x个质数。boolisprime[100000010];//isprime[i]=1表示:i是素数intprime[6000010],cnt=0;//prime存质数voidgetprime(intn){//筛到n也就是n以内的质数memset(is......