【蓝桥杯集训11】BFS(4 / 4)
创始人
2024-05-30 00:10:16
0

目录

844. 走迷宫 - BFS求最短路

1233. 全球变暖 - BFS

1、统计未被淹没岛屿数

2、直接统计被淹没岛屿数 

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 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=0&&ny

1233. 全球变暖 - BFS

活动 - AcWing

题目:

.表示海洋,#表示陆地

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

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

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

1、统计未被淹没岛屿数

思路:

  • 通过bfs统计出总岛屿数
  • bfs统计出未淹没的岛屿数 —— 如果一块陆地四周陆地块数为4,则说明该岛屿未被淹没
  • 最后 被淹没岛屿数 = 总岛屿数 - 未被淹没岛屿数
/**道阻且长,行则将至*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,res;public static void bfs(int x,int y){Queue q=new LinkedList<>();q.offer(new PII(x,y));boolean f=false;st[x][y]=1;while(!q.isEmpty()){int cnt=0;var 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=0&&ny

2、直接统计被淹没岛屿数 

思路:

  • 遍历岛屿,从某块陆地入手开始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 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

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

对于每一个状态,我们将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 q=new LinkedList<>();Map 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

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 q=new LinkedList<>();q.offer(x);st[x]=1;int res=0;for(int k=0;k0){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;}
}*/

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...