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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费