BFS中的Flood Fill和最短路模型

2024-02-26 14:12
文章标签 模型 bfs 短路 fill flood

本文主要是介绍BFS中的Flood Fill和最短路模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

BFS:1、“求最小” 用bfs第一次搜到的值就是最小值

           2、基迭代,不会爆栈 

 845. 八数码 - AcWing题库

import java.util.*;public class Main{public static void swap(char[] arr, int a, int b){char temp = arr[a];arr[a] = arr[b];arr[b] = temp;}public static int bfs(String start, String end){Map<String, Integer> map = new HashMap<>();//用来存储到达每种状态要走的距离Queue<String> q = new LinkedList<>();q.offer(start);map.put(start, 0);int[] dx = {-1,0,1,0}, dy = {0,1,0,-1};//上下左右四个方向while(!q.isEmpty()){String t = q.poll();//取出队头元素int k = t.indexOf('x');//找到元素x在这个字符串里的位置int x = k / 3;//找到等同在二维数组里面的坐标int y = k % 3;if(t.equals(end)) return map.get(t);//如果这时候已经相同了,就提前结束for(int i = 0; i < 4; i ++){//进行上下左右四种方案int a = x + dx[i], b = y + dy[i];//之前那种位移量的方法if(a < 3 && a >= 0 && b < 3 && b >= 0){//如果没有超出边界char[] arr = t.toCharArray();swap(arr, k, a * 3 + b);//交换位置,二维转化成一维//将交换位置后的字符数组变成新的字符串String str = new String(arr);if(map.get(str) == null){//说明这种状态还没有走到过map.put(str, map.get(t) + 1);//交换数加1q.offer(str);//加入队列}}}}return -1;}public static void main(String[] args){Scanner sc = new Scanner(System.in);String start = "";for(int i = 1; i <= 9; i ++){String s = sc.next();start += s;}String end = "12345678x";System.out.print(bfs(start, end));}
}

Flood Fill算法:

        可以在线性的时间复杂度内,找到某个点所在的连通块。

1097. 池塘计数 - AcWing题库 

import java.util.*;
import java.io.*;class PII{int x, y;public PII(int x, int y){//一个点的横纵坐标this.x = x;this.y = y;}
}public class Main{static int N = 1010, M = N * N;static int n, m;static PII[] q = new PII[M];static char[][] g = new char[N][N];static boolean[][] st = new boolean[N][N];public static void bfs(int x, int y){int hh = 0, tt = -1;q[++ tt] = new PII(x, y);//把这个点加入队列while(hh <= tt){PII t = q[hh ++];//取出队头int a = t.x;//横坐标int b = t.y;//纵坐标for(int i = a - 1; i <= a + 1; i ++){for(int j = b - 1; j <= b + 1; j ++){if(i == a && j == b) continue;if(i < 0 || j < 0 || i >= n || j >= m) continue;//如果就是这个点if(g[i][j] == '.' || st[i][j]) continue;//如果不是水或者是已经遍历过了q[++ tt] = new PII(i, j);//把这个点加入队列st[i][j] = true;//标记位遍历过}}}}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 = 0; i < n; i ++){String str = br.readLine();char[] arr = str.toCharArray();for(int j = 0; j < m; j ++){g[i][j] = arr[j];}}int cnt = 0;//记录遍历了多少个连通块for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++){if(g[i][j] == 'W' && !st[i][j]){//如果是水,而且没有遍历过bfs(i, j);cnt ++;}}}System.out.print(cnt);}
}

 

1098. 城堡问题 - AcWing题库

import java.util.*;class PII{int x, y;public PII(int x, int y){this.x = x;this.y = y;}
}public class Main{static int N = 60, M = N * N;static int n, m;static int[][] g = new int[N][N];static PII[] q = new PII[M];static boolean[][] st = new boolean[N][N];public static int bfs(int x, int y){int hh = 0, tt = -1;//队头和队尾int[] dx = {0, -1, 0, 1}, dy = {-1, 0, 1, 0};//西北东南四个方向q[++ tt] = new PII(x, y);//加入队列st[x][y] = true;//标记为已经遍历过int res = 0;//面积while(hh <= tt){PII t = q[hh ++];//取出元素res ++;//取出一个就加上一个for(int i = 0; i < 4; i ++){int a = t.x + dx[i];//四个方向int b = t.y + dy[i];if(a < 0 || b < 0 || a >= n || b >= m) continue;//越界if(st[a][b]) continue;//如果已经遍历过if((g[t.x][t.y] >> i & 1) == 1) continue;//用二进制来表示墙q[++ tt] = new PII(a, b);//加入队列st[a][b] = true;//标记为已经遍历过}}return res;}public static void main(String[] args){Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();for(int i = 0; i < n; i++){for(int j = 0; j < m; j ++){g[i][j] = sc.nextInt();}}int cnt = 0;//连通块的数量int area = 0;//面积for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++){if(!st[i][j]){area = Math.max(area, bfs(i, j));cnt ++;}}}System.out.println(cnt);System.out.println(area);}
}

 

1106. 山峰和山谷 - AcWing题库

import java.util.*;class PII{int x, y;public PII(int x, int y){this.x = x;this.y = y;}
}public class Main{static int N = 1010, M = N * N;static int n;static int[][] g = new int[N][N];static boolean[][] st = new boolean[N][N];static PII[] q = new PII[M];static boolean has_higher, has_lower;public static void bfs(int x, int y){int hh = 0, tt = -1;q[++ tt] = new PII(x, y);st[x][y] = true;//标记为走过while(hh <= tt){PII t = q[hh ++];for(int i = t.x - 1; i <= t.x + 1; i ++){for(int j = t.y - 1; j <= t.y + 1; j ++){if(t.x == i && t.y == j) continue;if(i < 0 || j < 0 || i >= n || j >= n) continue;if(g[i][j] != g[t.x][t.y]){//如果高度不相等if(g[i][j] > g[t.x][t.y]) has_higher = true;else has_lower = true;}else if(!st[i][j]){//如果高度相等st[i][j] = true;//标记为走过q[++ tt] = new PII(i, j);//存入队列}}}}}public static void main(String[] args){Scanner sc = new Scanner(System.in);n = sc.nextInt();for(int i = 0; i < n; i ++){for(int j = 0; j < n; j ++){g[i][j] = sc.nextInt();}}int peak = 0;int vally = 0;for(int i = 0; i < n; i ++){for(int j = 0; j < n; j ++){if(!st[i][j]){//如果没走过has_higher = false;has_lower = false;bfs(i, j);if(!has_lower) vally ++;//只要没有比他矮的,那么他就是山谷if(!has_higher) peak ++;//只要没有比他高的,那么就是山峰}}}System.out.print(peak + " " + vally);}
}

最短路问题

844. 走迷宫 - AcWing题库 是迷宫问题的简单版(迷宫问题要存路径)

1076. 迷宫问题 - AcWing题库

import java.util.*;
import java.io.*;class PII{int x, y;public PII(int x, int y){this.x = x;this.y = y;}
}public class Main{static int N = 1010, M = N * N, n;static int[][] g = new int[N][N];static PII[] q = new PII[M];static PII[][] pre = new PII[N][N];public static void bfs(int x, int y){int hh = 0, tt = -1;int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};//四个方向q[++ tt] = new PII(x, y);pre[x][y] = new PII(0, 0);//终点是由哪个点遍历来的while(hh <= tt){PII t = q[hh ++];for(int i = 0; i < 4; i ++){int a = t.x + dx[i];int b = t.y + dy[i];if(a >= n || b >= n || a < 0 || b < 0) continue;//边界if(g[a][b] == 1) continue;//墙if(pre[a][b].x != -1) continue;//如果前一个点的横坐标不为-1,那么说明遍历过q[++ tt] = new PII(a, b);//加入队列pre[a][b] = t;//这个点是由上一点过来的标记一下}}}public static void main(String[] args)throws IOException{BufferedReader br = new BufferedReader(new InputStreamReader(System.in));n = Integer.parseInt(br.readLine());for(int i = 0; i < n; i ++){String[] str = br.readLine().split(" ");for(int j = 0; j < n; j ++){g[i][j] = Integer.parseInt(str[j]);pre[i][j] = new PII(-1, -1);//标记为没遍历过}}bfs(n - 1, n - 1);//倒着来遍历PII end = new PII(0, 0);//输出路径while(true){System.out.println(end.x + " " + end.y);if(end.x == n - 1 && end.y == n - 1) break;end = pre[end.x][end.y];}}
}

 

188. 武士风度的牛 - AcWing题库

import java.util.*;
import java.io.*;class PII{int x, y;public PII(int x, int y){this.x = x;this.y = y;}
}public class Main{static int N = 200, M = N * N;static int n, m;static char[][] g = new char[N][N];static PII[] q = new PII[M];static int[][] dist = new int[N][N];public static int bfs(int a, int b){int hh = 0, tt = -1;int[] dx = {-2, -2, -1, 1, 2, 2, 1, -1};//八个方向int[] dy = {-1, 1, 2, 2, 1, -1, -2, -2};q[++ tt] = new PII(a, b);//加入队列dist[a][b] = 0;while(hh <= tt){PII t = q[hh ++];for(int i = 0; i < 8; i ++){int x = t.x + dx[i];int y = t.y + dy[i];if(x >= n || y >= m || x < 0 || y < 0) continue;//边界if(dist[x][y] != -1) continue;//如果走过了if(g[x][y] == '*') continue;//障碍if(g[x][y] == 'H') return dist[t.x][t.y] + 1;//到达目标dist[x][y] = dist[t.x][t.y] + 1;//步数加1q[++ tt] = new PII(x, y);//加入队列}}return -1;}public static void main(String[] args)throws IOException{BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String[] s = br.readLine().split(" ");m = Integer.parseInt(s[0]);n = Integer.parseInt(s[1]);for(int i = 0; i < n; i ++){String str = br.readLine();char[] arr = str.toCharArray();for(int j = 0; j < m; j ++){g[i][j] = arr[j];dist[i][j] = -1;//标记为没有走过}}for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++){if(g[i][j] == 'K'){System.out.print(bfs(i, j));}}}}
}

 

1100. 抓住那头牛 - AcWing题库

import java.util.*;public class Main{static int N = 200010, n, k;static int[] dist = new int[N];static int[] q = new int[N];public static int bfs(){int hh = 0, tt = -1;q[++ tt] = n;dist[n] = 0;Arrays.fill(dist, -1);//初始化表示没来过while(hh <= tt){int t = q[hh ++];if(t == k) return dist[k] + 1;//到达终点,结果加1if(t - 1 >= 0 && dist[t - 1] == -1){dist[t - 1] = dist[t] + 1;q[++ tt] = t - 1;}if(t + 1 < N && dist[t + 1] == -1){dist[t + 1] = dist[t] + 1;q[++ tt] = t + 1;}if(2 * t < N && dist[2 * t] == -1){dist[2 * t] = dist[t] + 1;q[++ tt] = 2 * t;}}return -1;}public static void main(String[] args){Scanner sc = new Scanner(System.in);n = sc.nextInt();k = sc.nextInt();System.out.print(bfs());}
}

 

这篇关于BFS中的Flood Fill和最短路模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/749130

相关文章

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee

DeepSeek模型本地部署的详细教程

《DeepSeek模型本地部署的详细教程》DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私,在本地成功部署DeepSe... 目录一、环境准备(一)硬件需求(二)软件依赖二、安装Ollama三、下载并部署DeepSeek模型选