DFS:深搜+回溯+剪枝解决矩阵搜索问题

                                               创作不易,感谢三连!! 

一、N皇后

. - 力扣(LeetCode)

class Solution {
public:
    vector<vector<string>> ret;
    vector<string> path;
    bool checkcol[9];
    bool checkdig1[18];
    bool checkdig2[18];
    int n;
    vector<vector<string>> solveNQueens(int _n) 
    {
        n=_n;
        path.resize(n);
        for(int i=0;i<n;++i)  path[i].append(n,'.');//先全部初始化成.
         dfs(0);
         return ret;
    }

    void dfs(int row)
    {
        if(row==n) {ret.push_back(path);return;}
        for(int col=0;col<n;++col)//枚举每一行的每个元素
        {
            if(checkcol[col]==false&&checkdig1[n+row-col]==false&&checkdig2[row+col]==false)//n+row-col防止越界
            {
               path[row][col]='Q';
               checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=true;
                dfs(row+1);
                //恢复现场
               path[row][col]='.';
               checkcol[col]=checkdig1[n+row-col]=checkdig2[row+col]=false;
            }
        }
    }
};

二、有效的数独

. - 力扣(LeetCode)

class Solution {
public:
    bool checkrow[9][10];
    bool checkcol[9][10];
    bool checkgrid[3][3][10];
    bool isValidSudoku(vector<vector<char>>& board) 
    {
         for(int row=0;row<9;++row)
         {
            for(int col=0;col<9;++col)
            {
                if(board[row][col]!='.')
                {
                    int num=board[row][col]-'0';
                    if(checkrow[row][num]||checkcol[col][num]||checkgrid[row/3][col/3][num]) return false;
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
                }
            }
         }
         return true;
    }
};

三、解数独

. - 力扣(LeetCode)

class Solution {
public:
    bool checkrow[9][10];
    bool checkcol[9][10];
    bool checkgrid[3][3][10];
    void solveSudoku(vector<vector<char>>& board) 
    {
        //初始化
       for(int row=0;row<9;++row)
         for(int col=0;col<9;++col)
         {
            if(board[row][col]!='.')
            {
                int num=board[row][col]-'0';
                checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
            }
         }
        dfs(board);
    }
        bool dfs(vector<vector<char>> &board)//bool用来告诉上一层决策是正确的
         {
           for(int row=0;row<9;++row)
            for(int col=0;col<9;++col)
         {
            if(board[row][col]=='.')
            {
              //开始尝试填数
              for(int num=1;num<=9;++num)
              {
                if(!checkrow[row][num]&&!checkcol[col][num]&&!checkgrid[row/3][col/3][num])
                {
                    //说明能填,就填上
                    board[row][col]=num+'0';
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=true;
                    if(dfs(board)) return true;//去下一个位置填,如果填成功了,返回true
                    //恢复现场
                    board[row][col]='.';
                    checkrow[row][num]=checkcol[col][num]=checkgrid[row/3][col/3][num]=false;
                }
              }
              return false;//1-9没有一个数能填,说明决策错误
            }
         }
            return true;//安全地填完了,返回true
         }
};

四、单词搜索

. - 力扣(LeetCode)

class Solution {
public:
    bool check[6][6];//用来标记选过的位置
    int m,n;
    vector<vector<char>> board;
    string word;
    bool exist(vector<vector<char>>& _board, string _word) 
    {
        board=_board;
        word=_word;
        m=board.size();
        n=board[0].size();
        for(int i=0;i<m;++i)
         for(int j=0;j<n;++j)
          {
             if(board[i][j]==word[0])
             {
                check[i][j]=true;
                if(dfs(i,j,1))  return true;
                check[i][j]=false;
             }
          }
          return false;
    }
    //用向量的方式来定义
     int dx[4]={0,0,-1,1};
     int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
    bool dfs(int i,int j,int pos)
    {
        if(pos==word.size())  return true;
        for(int k=0;k<4;++k)
        {
           int x=i+dx[k],y=j+dy[k];
           if(x>=0&&x<m&&y>=0&&y<n&&check[x][y]==false&&board[x][y]==word[pos])
           {
               check[x][y]=true;
               if(dfs(x,y,pos+1)) return true;
               check[x][y]=false;
           }
        }
        return false;//如果四个方向都找不到,说明确实没有可填的数,直接返回
    }
};

五、黄金旷工

. - 力扣(LeetCode)

class Solution {
public:
    int ret=0;
    bool check[15][15];
    int m,n;
    int getMaximumGold(vector<vector<int>>& grid) 
    {
      m=grid.size();
      n=grid[0].size();
      for(int i=0;i<m;++i)
        for(int j=0;j<n;++j)
          {
            if(grid[i][j])
            {
                check[i][j]=true;
                dfs(grid,i,j,grid[i][j]);
                check[i][j]=false;
            }
          }
          return ret;
     }
      //用向量的方式来定义
     int dx[4]={0,0,-1,1};
     int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
     void dfs(vector<vector<int>>& grid,int i,int j,int count)
     {
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y])
            {
                check[x][y]=true;
                dfs(grid,x,y,count+grid[x][y]);
                check[x][y]=false;
            }
        }
        ret=max(count,ret);
        //for循环结束,确实没得填了,更新
     }
};

六、不同路径III

. - 力扣(LeetCode)

class Solution {
public:
    int ret;
    bool check[20][20];//用来标记
    int m,n,step;//step用来统计可以走的方格个数
    int uniquePathsIII(vector<vector<int>>& grid) 
    {
        ret=0;
        m=grid.size();
        n=grid[0].size();
        step=0;
        int bx=0,by=0;//记录起点
        //先找起点
        for(int i=0;i<m;++i)
          for(int j=0;j<n;++j)
            {
                if(grid[i][j]==0) ++step;
                else if(grid[i][j]==1) 
                {
                    bx=i;
                    by=j;
                }
            }
        step+=2;//把起点和终点算上,最后走到终点的时候就可以返回了
        check[bx][by]=true;
        dfs(grid,bx,by,1);
        return ret;
    }
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0}; //就可以将4个方向改变成一个for循环
    void dfs(vector<vector<int>>& grid,int i,int j,int count)
    {
        if(grid[i][j]==2&&count==step) {++ret;return;}
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y]!=-1)
            {
                check[i][j]=true;
                dfs(grid,x,y,count+1);
                check[i][j]=false;
            }
        }
    }
};

七、小总结

1、矩阵搜索问题经常要用到向量,也就是我们可以通过dx和dy来帮助我们定义方向

2、矩阵搜索要确保走过的位置不再走过,所以此时有两个策略:

(1)标记数组,比较常用

(2)修改原矩阵的内容,但是这样做的话要我们要确保最后能够把它复原 

3、dfs的返回值不一定是void,如果该题目并不只是完全地去统计,而是涉及到我们做出的选择可能会错误的时候,这个时候我们就需要通过bool类型的返回值来帮助我们判断当前的填法是否正确。比如解数独和单词搜索问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/517365.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW电动汽车供电设备接触电流测试

LabVIEW电动汽车供电设备接触电流测试 随着电动汽车技术的迅猛发展和普及率的不断提高&#xff0c;电动汽车供电设施的电气安全显得尤为重要。为了优化电动汽车供电设备接触电流的测试方案&#xff0c;设计了一种基于LabVIEW的测试方案&#xff0c;通过平台校准测试和电动汽车…

Stable diffusion 加载扩展列表报错解决方法

项目场景&#xff1a; 在使用Stable diffusion webui时&#xff0c;使用扩展列表出现错误 问题描述 点击loadfrom后&#xff0c;出现加载扩展列表报错 原因分析&#xff1a; 下载的扩展的时候&#xff0c;都是github 的url&#xff0c;需要科学上网&#xff0c;如果不能科学…

P6维护:Oracle P6服务性能优化

前言 本文将介绍如何对ORACLE Primavera P6 EPPM软件进行性能调优&#xff0c;考虑到P6主要采用JAVA语言编制&#xff0c;且其使用的是Weblogic Server应用服务器部署P6各项服务器&#xff0c;其性能优化的原理便是基于其JVM特征参数进行设置 方法一&#xff1a;修改配置文件…

探索前端架构:MVC、MVVM和MVP模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

前端三剑客 —— CSS (第六节)

目录 内容回顾&#xff1a; 弹性布局属性介绍 案例演示 商品案例 布局分析 登录案例 网格布局 内容回顾&#xff1a; 变量&#xff1a;定义变量使用 --名称&#xff1a;值&#xff1b; 使用变量&#xff1a; 属性名&#xff1a;var&#xff08;--名称&#xff09;&a…

压缩 JavaScript

压缩 JavaScript 并关注压缩后的块大小以实现最佳性能。过高的 JavaScript 打包粒度有助于消除重复项和缓存&#xff0c;但可能在 50-100 块范围内受到较差的压缩和加载影响&#xff08;由于浏览器进程、缓存检查等&#xff09;。最终&#xff0c;选择最适合您的压缩策略。 Jav…

蓝桥杯刷题day13——玩游戏【算法赛】

一、问题描述 小 A 和小 B 两个人在海边找到了 n 个石子&#xff0c;准备开始进行一些游戏&#xff0c;具体规则如下&#xff1a;小 B 首先将 n 个石子分成若干堆&#xff0c;接下来从小 A 开始小 A 和小 B 轮流取石子&#xff0c;每次可以任选一堆石子取走任意个&#xff0c;…

(CVPR2024)DragGAN作者新作DiffMorpher:可以实现两张图像间的平滑变形

相信大家在网上看过一些图像变换的动图以及视频。比如生成两张人脸之间的渐变图。 狮子变老虎 那么这种功能是如何实现的呢&#xff1f; 计算机科学中有一种专门描述此应用的任务—图像变形(image morphing)。给定两张图像&#xff0c;图像变形算法会输出一系列合理的插值图像…

Redis数据库:概念、安装及常用操作命令

目录 前言 一、数据库概述 1、关系型数据库&#xff08;RDBMS&#xff09; 1.1 产生背景 1.2 概念 1.3 特点 1.4 优缺点 1.5 常见主流关系型数据库 2、非关系型数据库&#xff08;NoSQL&#xff09; 2.1 产生背景 2.2 概念 2.3 特点 2.4 优缺点 2.5 常见主流非关…

Mybatis--TypeHandler使用手册

TypeHandler使用手册 场景&#xff1a;想保存user时 teacher自动转String &#xff0c;不想每次保存都要手动去转String&#xff1b;从DB查询出来时&#xff0c;也要自动帮我们转换成Java对象 Teacher Data public class User {private Integer id;private String name;priva…

labview如何创建2D多曲线XY图和3D图

1如何使用labview创建2D多曲线图 使用“索引与捆绑簇数组”函数将多个一维数组捆绑成一个簇的数组&#xff0c;然后将结果赋值给XY图&#xff0c;这样一个多曲线XY图就生成了。也可以自己去手动索引&#xff0c;手动捆绑并生成数组&#xff0c;结果是一样的 2.如何创建3D图 在…

hadoop在linux上启动成功了,但是浏览器访问不了

根据网上的资料进行安装hadoop的伪集群 都安装成功&#xff0c;并且启动也成功了&#xff0c;如下图所示&#xff1a; 2、但是在浏览器上确是怎么也访问不了&#xff0c; 解决思路&#xff0c; 2.1、根据网上的一些文章处理解决是关闭防火墙&#xff0c; 2.1.1、我根据操作步骤…

【Python】RGB颜色对照表

专栏文章索引&#xff1a;Python 这里是我收集的几个RGB颜色对照网站&#xff1a; RGB颜色对照表 (oschina.net) RGB Color Codes Chart &#x1f3a8; (rapidtables.com) Colors RGB and RGBA (w3schools.com) Color Hex - ColorHexa.com Color Picker — HTML Color Cod…

CSRF介绍及Python实现

CSRF 文章目录 CSRF1. CSRF是什么&#xff1f;2. CSRF可以做什么&#xff1f;3. CSRF漏洞现状4. CSRF的原理5. 举例说明6. CSRF的防御Python示例 1. CSRF是什么&#xff1f; CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;中文名称&#xff1a;跨站请求…

按照指定的分隔符和次数从右侧开始分割字符串元素numpy.char.rsplit()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 按照指定的分隔符和次数 从右侧开始分割字符串元素 numpy.char.rsplit() [太阳]选择题 请问关于以下代码表述错误的选项是&#xff1f; import numpy as np a np.array([a b c, x,y,z, 1 2,…

江协STM32:定时器定时中断和定时器定时闹钟

定时器中断 新建文件 按这个图来编写程序 第一步&#xff1a;RCC开启时钟&#xff0c;定时器到基准时钟和整个外设到工作时钟就会同时打开 第二步&#xff1a;选择时基单元的时钟源&#xff0c;对于定时中断选择内部时钟源 第三步&#xff1a;配置时基单元&#xff0c;ARR,P…

Linux第2课Windows下的环境配置-虚拟机安装

文章目录 Linux第2课Windows下的环境配置-虚拟机安装一、VMware虚拟机的安装&#xff08;一&#xff09;安装VMware&#xff08;二&#xff09;启动电脑本地的VMware相关服务 二、VirtualBox安装 Linux第2课Windows下的环境配置-虚拟机安装 本节课程提供了两种虚拟机的安装方法…

【Django开发】0到1美多商城项目md教程第5篇:短信验证码,1. 避免频繁发送短信验证码逻辑分析【附代码文档】

美多商城完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;欢迎来到美多商城&#xff01;&#xff0c;项目准备。展示用户注册页面&#xff0c;创建用户模块子应用。用户注册业务实现&#xff0c;用户注册前端逻辑。图形验证码&#xff0c;图形验证码接口设…

Java笔试题总结

HashSet子类依靠()方法区分重复元素。 A toString(),equals() B clone(),equals() C hashCode(),equals() D getClass(),clone() 答案:C 解析: 先调用对象的hashcode方法将对象映射为数组下标,再通过equals来判断元素内容是否相同 以下程序执行的结果是&#xff1a; class X{…

NKCTF2024 re VM?VM!WP

逻辑似乎很简单&#xff08;个鬼啊&#xff09; 这个函数是把输入的字符转化为二进制并倒序存储 sub_1570太大了加载不出来&#xff0c;应该是加密的主逻辑&#xff0c;目的是需要输出1 可以通过删除栈的方法强行转化伪代码 首先删掉这部分 9A0改小点 这个也是 栈这里U一下再…