【蓝桥杯集训11】BFS(4 / 4)

news2024/11/18 15:26:50

目录

844. 走迷宫 - BFS求最短路

1233. 全球变暖 - BFS

845. 八数码 - 最短路BFS + 状态表示 + 一二维坐标转换

为什么BFS保证走的是最短路?

一二维坐标转换(n×n矩阵)

1562.微博转发 - BFS按层遍历 + 有向图


844. 走迷宫 - BFS求最短路

活动 - AcWing

题目:

 

思路:

为什么就算有多条通路,它总能输出最小距离?
因为当第一个点到达终点时,它一定是最短距离,并且会将终点标记,那么其他点再也无法到达终点,也更新不了初始点到终点的距离

将起点(0,0)入队,上下左右走,只要在合法的范围内且不碰到墙且没有走过,则入队

BFS就是将所有能走的路都走,第一条能走通的路一定是最短路

/*
    *道阻且长,行则将至*
    author:Roye_ack
*/
import java.util.*;
import java.io.*;
import java.math.*;
 
class Main
{
    static int N=300010;
    static int[][] g=new int[110][110];
    static int[][] d=new int[110][110]; //记录该点到起点的距离
    static int[][] st=new int[110][110];
    static int[] dx={-1,1,0,0};
    static int[] dy={0,0,-1,1};
    static int n,m;
    
    public static int bfs()
    {
        d[0][0]=0;
        
        Queue<PII> q=new LinkedList<>();
        q.offer(new PII(0,0));
        
        while(!q.isEmpty())
        {
            PII t=q.poll();
            for(int i=0;i<4;i++)
            {
                int nx=t.x+dx[i];
                int ny=t.y+dy[i];
                if(nx>=0&&nx<n&&ny>=0&&ny<m&&g[nx][ny]==0&&st[nx][ny]==0)
                {
                    q.offer(new PII(nx,ny));
                    d[nx][ny]=d[t.x][t.y]+1;
                    st[nx][ny]=1;
                }
            }
        }
        return d[n-1][m-1];
    }
    
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        n=rd.nextInt();
        m=rd.nextInt();
        
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
               g[i][j]=rd.nextInt();
            
        wt.print(bfs());
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

class PII
{
    int x,y;
    PII(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}

1233. 全球变暖 - BFS

活动 - AcWing

题目:

.表示海洋,#表示陆地

.......
.##....
.##....
....##.
..####.
...###.
.......

如果陆地的上下左右存在海洋,则该陆地被淹没

问有多少个岛屿会被完全淹没?

思路:

  • 遍历岛屿,从某块陆地入手开始bfs, 统计该岛屿的陆地总数total以及被淹没的陆地数submerge
  • 如果岛屿陆地总数==被淹没的陆地数,说明这个岛屿完全被淹没,则res++
  • 走过的陆地要标记,避免重复遍历
/*
    *道阻且长,行则将至*
    author:Roye_ack
*/
import java.util.*;
import java.io.*;
import java.math.*;
 
class Main
{
    static int N=1010;
    static char[][] g=new char[N][N];
    static int[][] st=new int[N][N];
    static int[] dx={-1,1,0,0};
    static int[] dy={0,0,-1,1};
    static int n;
    
    public static boolean bfs(int x,int y)
    {
        Queue<PII> q=new LinkedList<>();
        q.offer(new PII(x,y));
        st[x][y]=1;
        int total=0; //统计遍历的陆地数
        int submerge=0; //统计被淹没的陆地数
        while(!q.isEmpty())
        {
            var t=q.poll();
            total++;
            boolean f=false; //f判断该陆地是否被淹没
            for(int i=0;i<4;i++)
            {
                int nx=t.x+dx[i];
                int ny=t.y+dy[i];
                if(nx<0||nx>=n||ny<0||ny>=n) continue;
                if(st[nx][ny]==1) continue;
                if(g[nx][ny]=='.') //如果当前陆地上下左右存在海,则该陆地被淹没
                {
                    f=true;
                    continue;
                }
                st[nx][ny]=1;
                q.offer(new PII(nx,ny));
            }
            if(f) submerge++;
        }
        return total==submerge;
    }
    
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        n=rd.nextInt();
        int res=0;
        
        for(int i=0;i<n;i++)
        {
            String s=rd.next();
            for(int j=0;j<n;j++)
               g[i][j]=s.charAt(j);
        }
    
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]=='#'&&st[i][j]==0) //遍历岛屿
                {
                    if(bfs(i,j)) res++;
                }
                    
        wt.print(res);
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

class PII
{
    int x,y;
    PII(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}

845. 八数码 - 最短路BFS + 状态表示 + 一二维坐标转换

活动 - AcWing

题目:

给你一个3×3的华容道

1 2 3 
x 4 6 
7 5 8

x可以跟上下左右的数字进行交换

问移动到最后状态↓的最小步数是多少?

1 2 3
4 5 6
7 8 x

思路:

BFS求最短路,将x往上下左右四个方向走,如果之前不存在这种情况则步数在之前的基础上+1,BFS保证走的是最短路

为什么BFS保证走的是最短路?

因为BFS是一层层的搜索,假设边的权值都是1,那么每搜一次(即入队一层),路径长度+1,所以最先到终点的那条路径一定是最短的,而且因为走过的点有标记,所以每个点只会遍历一次,则遍历结束后就能知道最短路,所以用BFS可以求任意起点到终点的最短路径

我们可以将3×3矩阵的状态压缩成一维的 

x=idx/3  y=idx%3

用map储存  mp<string状态,int路径长度>

对于每一个状态,我们将x上下左右移动,直到搜索到答案 "12345678x"

一二维坐标转换(n×n矩阵)

设idx为一维坐标

一维→二维

x=idx/n;

y=idx%n;

二维→一维

idx=x*n+y;
/*
    *道阻且长,行则将至*
    author:Roye_ack
*/
import java.util.*;
import java.io.*;
import java.math.*;
 
class Main
{
    static int N=100010;
    static int[] dx={0,0,1,-1};
    static int[] dy={1,-1,0,0};
    
    static void swap(char[] a,int idx1,int idx2)
    {
        char t=a[idx1];
        a[idx1]=a[idx2];
        a[idx2]=t;
    }
    
    static int bfs(String start)
    {
        Queue<String> q=new LinkedList<>();
        Map<String,Integer> mp=new HashMap<>();
        
        String end="12345678x";
        q.offer(start);
        mp.put(start,0);
        
        while(!q.isEmpty())
        {
            var t=q.poll();
            if(t.equals(end)) return mp.get(t);
            int idx=t.indexOf('x');
            int x=idx/3,y=idx%3; //将x的一维下标转换成二维
            
            
            for(int i=0;i<4;i++)
            {
                int nx=x+dx[i],ny=y+dy[i];
                if(nx<0||nx>=3||ny<0||ny>=3) continue;
                
                char[] temp=t.toCharArray();
                swap(temp,idx,nx*3+ny); //交换位置
                String s=String.valueOf(temp);
                
                if(!mp.containsKey(s)) //如果之前没有走过这一步 则步数+1
                {
                    mp.put(s,mp.getOrDefault(t,0)+1);
                    q.offer(s);
                }
            }
        }
        
        return -1;
    }
    
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        String[] ss=rd.nextLine().split(" ");
        String start="";
        for(int i=0;i<ss.length;i++) start+=ss[i];
        wt.print(bfs(start));
        
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

 

1562.微博转发 - BFS按层遍历 + 有向图

https://www.acwing.com/problem/content/1564/

题目:

第一行给出n(n个用户) l(需要考虑的层数)

接下来n行格式:m——第i名用户关注的总人数  mi——这位用户关注的用户编号

最后有q个询问,问qi用户最大可能关注量

如果 B 是 A 的关注者,C 是 B 的关注者,那么 A 的第一层关注者是 B,第二层关注者是 C

思路:

对于每一个用户i,建立一个有向图

bfs遍历l层,遍历过用户的做标记 ,统计l层内未被标记的用户个数,即最大转发量

/*
    *道阻且长,行则将至*
    author:Roye_ack
*/
import java.util.*;
import java.io.*;
import java.math.*;
 
class Main
{
    static int N=1010,M=100010;
    static int[] h=new int[N],ne=new int[M],e=new int[M];
    static int idx,n,l;
    
    public static void add(int a,int b)
    {
        e[idx]=b;ne[idx]=h[a];h[a]=idx++;
    }
    
    public static int bfs(int x)
    {
        int[] st=new int[N];
        Queue<Integer> q=new LinkedList<>();
        q.offer(x);
        st[x]=1;
        
        int res=0;
        for(int k=0;k<l;k++)
        {
            int sz=q.size();
            while(sz-->0)
            {
                var t=q.poll();
                for(int i=h[t];i!=-1;i=ne[i])
                {
                    int j=e[i];
                    if(st[j]==0)
                    {
                        st[j]=1;
                        q.offer(j);
                        res++;
                    }   
                }
            }
        }
        
        return res;
    }
    
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        n=rd.nextInt();
        l=rd.nextInt();
        
        Arrays.fill(h,-1);
        
        for(int i=1;i<=n;i++)
        {
            int cnt=rd.nextInt();
            while(cnt-->0)
            {
                int x=rd.nextInt();
                add(x,i);
            }
        }
        
        int q=rd.nextInt();
        while(q-->0)
        {
            int t=rd.nextInt();
            wt.println(bfs(t));
        }
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

/*class PII
{
    int x,y;
    PII(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}*/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7安装中文字体

一、背景 最近一直在重写2021年毕设的前端页面&#xff0c;用vue3vite实现的响应式布局&#xff0c;目前完成10%。但在部署到Linux上时&#xff0c;遇到了服务端生成的中文验证码混乱的问题&#xff0c;通过远程断点&#xff0c;排除编码的问题&#xff0c;原来是由于Linux没有…

Linux网络编程 第六天

目录 学习目标 libevent介绍 libevent的安装 libevent库的使用 libevent的使用 libevent的地基-event_base 等待事件产生-循环等待event_loop 使用libevent库的步骤&#xff1a; 事件驱动-event 编写一个基于event实现的tcp服务器&#xff1a; 自带buffer的事件-buff…

深圳大学计软《面向对象的程序设计》实验14 运算符重载2和函数模板

A. 日期比较&#xff08;运算符重载之类型转换&#xff09; 题目描述 定义一个日期类CDate&#xff0c;包含属性&#xff1a;年、月、日&#xff0c;都是整数。 构造函数含单个参数&#xff0c;参数是八位整数&#xff0c;默认值为0&#xff0c;实现整数转为日期类型&#x…

【基于感知损失的无监督泛锐化】

PercepPan: Towards Unsupervised Pan-Sharpening Based on Perceptual Loss &#xff08;PercepPan&#xff1a;基于感知损失的无监督泛锐化&#xff09; 在基于神经网络的全色锐化文献中&#xff0c;作为地面实况标签的高分辨率多光谱图像通常是不可用的。为了解决这个问题…

C++初学笔记整理

目录 1. C关键字 2. 命名空间 1&#xff09;命名空间的引入和概述 2&#xff09;命名空间的定义 3&#xff09;std与命名空间的使用 4).相关特性 3. C输入&输出 4. 缺省参数 1 &#xff09;缺省参数概念 2&#xff09;使用及分类 a.全缺省 b.部分缺省 5. 函数…

力扣-337打家劫舍III(dp)

力扣-337打家劫舍III 1、题目 337. 打家劫舍 III 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为 root 。 除了 root 之外&#xff0c;每栋房子有且只有一个“父“房子与之相连。一番侦察之后&#xff0c;聪明的小偷意识到“这个地方的所有…

【FMCW 01】中频IF信号

FMCW信号 调频连续波(frequency modulated continuous wave&#xff0c;FMCW)顾名思义&#xff0c;就是对信号的频率进行线性调制的信号。 从时域上看&#xff0c;对频率的调制&#xff0c;就像一把连续的锯齿波。其中每一个锯齿叫做一个chirp&#xff0c;其持续的时间叫做ch…

Android仿微信选择图片

效果展示首先先添加用到的权限<uses-permission android:name"android.permission.INTERNET" /><!--获取手机存储卡权限--><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:nam…

java 包装类 万字详解(通俗易懂)

前言简介和溯源拆装箱String类和基本类型的相互转化String类和包装类型的相互转化八大包装类的常用方法汇总&#xff08;含代码演示&#xff09;一、前言 : 本节内容是我们《API-常用类》专题的最后一节了。本节内容主要讲包装类&#xff0c;内容包括但不限于包装类的诞生&…

Linux磁盘占满,如何清理磁盘空间

目录解决思路&#xff1a;先查linux磁盘为什么占满了&#xff0c;是什么导致的&#xff0c;这样才好去定位目录&#xff0c;清楚空间写者的问题是测试环境磁盘占满&#xff0c;原因是测试环境tomcat的日志都会保留&#xff0c;日志空间占用太大把linux磁盘占满&#xff0c;导致…

HTML 表单

HTML 表单和输入 HTML 表单用于收集不同类型的用户输入。 在线实例 创建文本字段 (Text field) 本例演示如何在 HTML 页面创建文本域。用户可以在文本域中写入文本。 创建密码字段 本例演示如何创建 HTML 的密码域。 &#xff08;在本页底端可以找到更多实例。&#xff09; …

信息安全与数学基础-笔记-①整数的可除性

知识目录整除素数带余除法最大公因数&#xff08;欧几里德算法&#xff09;裴蜀等式最小公倍数❀标准分解式❀标准分解式求最大公因数标准分解式求最小公倍数整除 a bq 公式表达的意思&#xff1a;b整除a&#xff0c;a可被b整除 用符号表示&#xff1a;b | a 否则&#xff1a…

【SpringMVC】SpringMVC程序开发

SpringMVC程序开发 文章目录SpringMVC程序开发:one:认识SpringMVC什么是SpringMVCMVC思想:two:获取请求参数创建SpringMVC项目建立路由连接获取请求参数获取urlEncoded格式参数获取表单标签参数获取Json格式参数获取URL中的参数上传图片获取请求信息获取请求header获取cookie创…

Linux -- 信号控制进程 Kill 命令 简引

Kill 命令 &#xff1a;给进程发送信号 &#xff1a;[rootfsw ~]# kill -l # 可以列出 当前所有的信号量 比较常用的就是 &#xff1a;1) SIGHUP 重新加载配置2) SIGINT 键盘中断^C 即 Ctrl C3) SIGQUIT 键盘退出9) SIGKILL 强制终止15) SIGTERM 终止&#xff08;正…

『OPEN3D』点云表面重建

目录 1 点云法线一致性估计 2 点云的表面重建 1 Alpha shapes reconstruction 2 Ball pivoting reconstruction 3 poisson surface reconstruction 1 点云法线一致性估计 在点云处理的章节中已经介绍使用estimate_normals来生成点云的发现信息&#xff0c;但该方法通过拟合…

业务流程测试

用例设计主要问题主要问题存在于&#xff1a;1、测试点分析&#xff1a;逻辑性不强对于整个页面功能划分不清晰&#xff1b;不同测试点归类不清晰&#xff1b;不能形成相对固定的套路&#xff0c;书写耗费大量时间...2、测试用例&#xff1a;关于&#xff0c;要细致到什么程度&…

一个供参考的计算机的学习路线

本文是介绍如何成为一个Geek&#xff0c;一个真正的计算机高手。 适合有成为IT领域技术大牛的人参考。 写给大一新生和所有向深耕IT领域的人&#xff0c;避免走一些弯路。 仅代表个人想法&#xff0c;供批判性参考。 第一门入门的必备功课-语法与算法 什么是计算机&#xff1f…

力扣sql简单篇练习(二十二)

力扣sql简单篇练习(二十二) 1 上月播放的儿童适宜电影 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # Write your MySQL query statement belowSELECT titleFROM ContentWHERE kids_contentY AND content_typeMoviesAND c…

MYSQL性能分析,Explain

文章目录一、MYSQL常见瓶颈二、ExplainExplain是什么一、MYSQL常见瓶颈 CPU&#xff1a; CPU饱和IO&#xff1a;磁盘IO速度过慢。服务器的硬件性能瓶颈。 二、Explain Explain是什么 使用explain关键字可以模拟优化器执行sql查询语句&#xff0c;从而知道mysql如何处理你的…

Python 随机漫步

目录 1. 创建 RandomWalk 类 2. 选择方向 3. 绘制随机漫步图 4. 总结 本篇博客将使用 Python 来生成随机漫步数据&#xff0c;在使用 Matplotlib 以引人注目的方式将这些数据呈现出来。 随机漫步 是这样行走得到的路径&#xff1a;每次行走都是完全随机的、没有明确…