前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BFS广度优先遍历——Acwing 844. 走迷宫

BFS广度优先遍历——Acwing 844. 走迷宫

作者头像
用户10604450
发布2024-03-15 14:41:23
930
发布2024-03-15 14:41:23
举报
文章被收录于专栏:练习两年半练习两年半

1.BFS简介

我们可以将bfs当做一个成熟稳重的人,一个眼观六路耳听八方的人,他每次搜索都是一层层的搜索,从第一层扩散到最后一层,BFS可以用来解决最短路问题。

2.基本思想

从初始状态S开始,利用规则,生成所有可能的状态。构成树的下一层节点,检查是否出现目标状态G,若未出现,就对该层所有状态节点,分别顺序利用规则。生成再下一层的所有状态节点,对这一层的所有状态节点检查是否出现G,若未出现,继续按上面思想生成再下一层的所有状态节点,这样一层一层往下展开。直到出现目标状态为止。

3.Acwing 844. 走迷宫

3.1

3.2bfs 过程手动模拟:

从起点开始,往前走第一步,记录下所有第一步能走到的点,然后从所第一步能走到的点开始,往前走第二步,记录下所有第二步能走到的点,重复下去,直到走到终点。输出步数即可。

3.3Ac代码

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;


public class Main{

    static int n,m,N=110;
    static int [][]p=new int[N][N];     //存储原始地图
    static boolean [][]state=new boolean[N][N];  //每个点是否走过
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String []s=br.readLine().split(" ");
        n=Integer.parseInt(s[0]);
        m=Integer.parseInt(s[1]);
        for (int i = 1; i <=n; i++) {
            s=br.readLine().split(" ");
            for (int j =1; j <=m; j++) {
                p[i][j]=Integer.parseInt(s[j-1]);
            }
        }
        bfs();
        br.close();
    }

    private static void bfs() {
        int x=1,y=1;
        Queue<Point> q=new ArrayDeque<>();  //创建队列存储走过的每一个点
        q.add(new Point(x,y,0));      //首先把第一个点存进队列
        int []dy={0,-1,0,1};
        int []dx={-1,0,1,0};
        while (!q.isEmpty()){
            Point head=q.poll();      //取出队首元素
            if(head.x==n &&head.y==m){   //如果走到出口
                System.out.println(head.step);
                return;
            }
            for (int i = 0; i < 4; i++) {   //往四个方向走
                x= head.x+dx[i]; y= head.y+dy[i];
                if(x>0 &&x<=n &&y>0 &&y<=m &&!state[x][y] &&p[x][y]==0){ //如果还没有走过并且可以走
                 state[x][y]=true;
                 q.add(new Point(x,y, head.step+1));
                }
            }
        }
    }

    static class Point{
        int x,y,step;
        Point(){
        }

        public Point(int x, int y, int step) {
            this.x = x;
            this.y = y;
            this.step = step;
        }
    }
}

4.Acwing 845. 八数码

4.1题目

4.2解题思路及模拟

暴力穷举。穷举出所有给定序列通过交换能得到的新序列,在穷举过程中保存交换次数。

在穷举过程中,如果出现了结果序列,就输出交换次数。

否则不能得到结果序列,输出 -1。

起始状态: 为 1 2 3 x 4 6 7 5 8

交换一次:

x 与上方元素交换得到: x 2 3 1 4 6 7 5 8

x 与右方元素交换得到: 1 2 3 4 x 6 7 5 8

x 与下方元素交换得到: 1 2 3 7 4 6 x 5 8

交换两次得到:

2 x 3 1 4 6 7 5 8

1 x 3 4 2 6 7 5 8

1 2 3 4 6 x 7 5 8

1 2 3 4 5 6 7 x 8

1 2 3 7 4 6 5 x 8

交换三次得到:

2 3 x 1 4 6 7 5 8

.....

1 2 3 4 5 6 7 8 x

.....

得到了最终结果,输出 3.

4.3Ac代码

代码语言:javascript
复制
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String []s=br.readLine().split(" ");
        String start="";
        for (int i = 0; i < s.length; i++) {
            start+=s[i];
        }
        System.out.println(bfs(start));
        br.close();
    }

    private static Integer bfs(String start) {
        String end="12345678x";
        Queue<String> q=new ArrayDeque<>(); //存储所有状态
        Map<String,Integer> state=new HashMap<>(); //存储每个状态得交换次数
        q.add(start);
        state.put(start,0); //存初始状态
        int dx[]={0,1,0,-1}; int dy[]={1,0,-1,0};//四个方向
        while (!q.isEmpty()){//枚举所有状态
            String head=q.poll();//取出头一个状态并向前寻找(head过程中不能修改,因为有四次变化 而位置都是map[t]+1)
            if(head.equals(end))    return state.get(head);
            int k=head.indexOf('x'); //找到x所在的下标
            int x=k/3,y=k%3;
            for (int i = 0; i < 4; i++) {
                int a=x+dx[i],b=y+dy[i];//变化状态之后x的下标
                if(a>=0 &&a<3 &&b>=0 &&b<3){  //变换后不出界的就是可用的
                char []ch=head.toCharArray();//字符串里面不能交换所以就到字符数组里
                swap(ch,k,a*3+b);
                String s=new String(ch);
                if(state.get(s)==null){//如果这个状态没出现过就存储这个状态
                    q.add(s);
                    state.put(s,state.get(head)+1);
                }
                }
            }
        }
        return -1;
    }

    private static void swap(char[] arr, int x, int y) {
        char c=arr[x];
        arr[x]=arr[y];
        arr[y]=c;
    }
}

5.结尾

如果对java中队列的使用方法不熟悉的话可以看下java叶新东老师的这篇文章

https://blog.csdn.net/qq_27184497/article/details/116093422?ops_request_misc=&request_id=&biz_id=102&utm_term=java%E4%B8%AD%E4%BD%BF%E7%94%A8quene&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-116093422.142^v73^pc_search_v2,201^v4^add_ask,239^v1^insert_chatgpt&spm=1018.2226.3001.4187

感谢你能看完, 如有错误欢迎评论指正,有好的思路可以交流一波,如果对你有帮助的话,点个赞支持下

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.BFS简介
  • 2.基本思想
  • 3.Acwing 844. 走迷宫
    • 3.1
      • 3.2bfs 过程手动模拟:
        • 3.3Ac代码
        • 4.Acwing 845. 八数码
          • 4.1题目
            • 4.2解题思路及模拟
              • 4.3Ac代码
              • 5.结尾
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档