算法笔记BFS篇:问题 B: DFS or BFS?

在这里插入图片描述

在这里插入图片描述

我的代码其实是有一丢丢小问题的(我在备注里也写了),我也没改,不过大致思路是正确的。

#include <cstdio>
#include<math.h>
#include<queue>
using namespace std;
//对于这道题,是需要有一个方法来更新地图的,也就是每选一部,就更新一次
//然后对于主函数就是,进行各个方向的判断,这道题dfs和BFS都可以,但是这题是放在BFS上的
//而且又是需要有字符串数组的参与
//这道题最巧妙的地方在于,他不判重复,所以最核心的就是,他只要走满8步。期间都没有问题的话,他就是一定可以的
char  mmap[8][8];
int stepx[9]={-1,1,0,0,-1,-1,1,1,0};
int stepy[9]={0,0,-1,1,-1,1,-1,1,0};
//bool mark[8][8]={false};
//写一个方法来判断这个点是否可以
int step;//用来表示记录的个数
bool judge(int x,int y){
    if(x<0||x>=8||y<0||y>=8)
        return false;//越界
    if(mmap[x][y]!='S')
    //如果没有被访问过,并且这个点不是石头的话,就可以访问
        return true;
    else
        return false;
}
//在写一个方法更新地图,本来我想的是在先判断这个位置是不是落石,如果是的话,那就把下面一个也变成落石,可是这样的话,就会对地图再一次更新
//可是这样不行,所以是需要从后往前开始移动的(和01背包一个道理)
void updatemap(){
    //遍历整个地图
    for(int i=7;i>=0;i--)
    for(int j=7;j>=0;j--){
        if(mmap[i][j]=='S'){
            //对他是不是最后一行进行分类,最后一行的话,直接换成*
            if(i==7)
                mmap[i][j]='.';
            else{
                //如果不是最后一行的话,这一行变成* 下一行变成S
                mmap[i][j]='.';
                mmap[i+1][j]='S';
            }

        }
    }
}
//然后开始就是BFS,我将其设置为bool形
bool BFS(int a,int b){
    //是需要创建一个队列的
    queue<char> p;
    p.push(mmap[a][b]);
    bool flag;//用来做标记
    while(!p.empty()){
        //再非空的条件下
        flag=false;
        char temp=p.front();
        if(temp=='A'||step>8)
            return true;//到终点直接返回
        //这个和普通的有点区别在于,每次对应点实时更新一下,这里出现的错误在于,不是当前的temp,而是当前位置的值,其实已经更新了。。
        if(temp=='S')
            return false;
        //再删去第一个
        p.pop();
        //再开始判断这些他的左右上下的点
        for(int k=0;k<=8;k++){
            //如果这个点可以的话,那就进行换位,可是难点在于,怎么换位之后还原呢,换位不是永久性的嘛,现在想的是 弄一个标记,如果可行的话,就进行一次换位
            //还是说 再弄一个重复的?
            int newa=a+stepx[k];
            int newb=b+stepy[k];
            if(judge(newa,newb)){
                //如果这个点可以的话,就进行换位,还是用那个标记的方法比较好
                flag=true;
                //然后这个点进栈,并把他标志为访问过了
                //mark[newa][newb]=true;
                p.push(mmap[newa][newb]);

            }

        }
        if(flag){
            //也就是这一层进行过换位的话,那就修改一次图
            updatemap();
            step+=1;

        }


    }
    return false;
}
int main(){
    int n;
    scanf("%d",&n);
    int q=1;
    while(q<=n){
        step=0;
       //用新学到的写字符串的方法
       for(int i=0;i<8;i++)
            scanf("%s",mmap[i]);
        //mark[7][0]=true;
       if(BFS(7,0))
        printf("Case #%d: YES\n",q);
       else
        printf("Case #%d: No\n",q);

        q++;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值