蓝桥训练3.3之DFS

目录

1, 棋盘挑战

 2、马蹄铁

3、不同路径数 

多多关注啊!!!


1, 棋盘挑战

 这道题和八皇后非常类似,具体的做法不再加以追叙,每一行代码都有备注

#include <bits/stdc++.h>
using namespace std;
const int N=15;
int path[N],ans,n;
bool col[N],dg[N*2],udg[N*2];//对角线的个数为N*,用于判断每一行、列,和对角线与反对角线有没有多余一个棋子;
void dfs(int x)//暴搜每一行
{
    if(x>n)//这个分支完成搜素,符合条件,
    {
        ans++;//答案加一
        if(ans<=3)//根据要求,输出字典序的前三种方案,
        {
            for(int i=1;i<=n;i++)
            cout<<path[i]<<' ';
            
            cout<<endl;
        }
        return;
    }
    for(int y=1;y<=n;y++)//暴搜每一列有没有数
    {
        if(!col[y]&&!dg[x+y]&&!udg[x-y+n])//这个棋子符合摆放条件
        {
            path[x]=y;//记录摆放位置
            col[y]=true,dg[x+y]=true,udg[x-y+n]=true;
            dfs(x+1);//又继续暴搜x+1行
            col[y]=false,dg[x+y]=false,udg[x-y+n]=false;//不符合条件的话,需要恢复现场
            path[x]=0;
        }
    }
}
int main(){
    cin>>n;
    dfs(1);
    cout<<ans<<endl;
}

 2、马蹄铁

 这道题每行代码有注释,不再单独写题解了

#include <bits/stdc++.h>
using namespace std;
const int N=10;
char h[N][N];
bool g[N][N];//g[N][N]用于标记这个方格是否被搜过
int ans,n;//用以记录(和)的数量,
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//定义偏移量
void dfs(int x,int y,int l,int r)
{
    g[x][y]=true;
    if(l==r)//找到了符合条件的字符串
    {
        ans=max(ans,l+r);
        g[x][y]=false;//恢复现场
        return;
    }
    for(int i=0;i<4;i++)//枚举上下左右的四个方格
    {
        int a=x+dx[i];
        int b=y+dy[i];
        if(a>=0&&a<n&&b>=0&&b<n&&!g[a][b])//没有越界且给g[a][b]没有被标记
        {
            if(h[a][b]=='('&&h[x][y]==')')continue;//")("这种一定不符合条件
            if(h[a][b]=='(')dfs(a,b,l+1,r);//l++
            else
            dfs(a,b,l,r+1);//r++
        }
    }
    g[x][y]=false;//恢复现场
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      cin>>h[i][j];
    if(h[0][0]=='(')//她只能移动到包含马蹄铁的方格区域内,当她进入该区域时就会拿起那里的马蹄铁               //如果是')',怎么拿ans都会是0
    dfs(0,0,1,0);//第一个方格符合条件,
    cout<<ans;
    return 0;
}

 错误反思:二维数组的输入没有正确,边界没有处理对

3、不同路径数 

#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;
unordered_set<int> ans;//开一个哈希表用于存数
const int N=8;
int g[N][N],n,m,k;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//偏移量用于上下左右走步
void dfs(int x,int y,int u,int num)//当前在走第u步,积累的数是num
{
    if(u==k)//已经走了k步了
    {
        ans.insert(num);
        return ;//结束一次枚举
    }
    else
    {
        for(int i=0;i<4;i++){
            int a=x+dx[i],b=y+dy[i];//上下左右走
            if(a>=0&&a<n&&b>=0&&b<m)//位置没有越界
            {
                dfs(a,b,u+1,num*10+g[a][b]);
            }
        }
    }
}
int main(){
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++){
          cin>>g[i][j];//输入数据
    }
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++){
          dfs(i,j,0,g[i][j]);//开始枚举,第一个数是g[i][j];
    }
    printf("%d\n",ans.size());
    return 0;
}

 对于unordered_set,可看这篇文章

(88条消息) C++常用语法——unordered_set_unordered_set 头文件_还没想好~的博客-优快云博客https://blog.youkuaiyun.com/LiuXF93/article/details/120899401?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167790093316800226582827%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167790093316800226582827&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-120899401-null-null.142%5Ev73%5Econtrol,201%5Ev4%5Eadd_ask,239%5Ev2%5Einsert_chatgpt&utm_term=unordered_set&spm=1018.2226.3001.4187

 对于dfs算法,在后期我会继续更新,也会更加详细

多多关注啊!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法第一深情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值