当前位置: 首页 > news >正文

代码随想录算法训练营四十六天|图论part04

岛屿问题(八)岛屿的周长

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿是被水包围,并且通过水平方向或垂直方向上相邻的陆地连接而成的。

你可以假设矩阵外均被水包围。在矩阵中恰好拥有一个岛屿,假设组成岛屿的陆地边长都为 1,请计算岛屿的周长。岛屿内部没有水域。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。之后 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示岛屿的周长。

输入示例

5 5
0 0 0 0 0 
0 1 0 1 0
0 1 1 1 0
0 1 1 1 0
0 0 0 0 0

输出示例

14

提示信息

岛屿的周长为 14。

数据范围:

1 <= M, N <= 50。

思路:

首先为了防止有的岛屿外没有水包围,我们给原有的矩阵外包一圈水。

之后遍历矩阵(不需要遍历外面那一圈水),如果当前坐标是陆地,那么遍历它上下左右看是否有水,如果有的话,那一条边就是周长的一部分,就需要算在周长里。

代码如下:

import java.util.*;public class Main{private static int ans=0;public static void main(String[] args){Scanner in=new Scanner(System.in);int n=in.nextInt();int m=in.nextInt();int[][] graph=new int[n+2][m+2];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){graph[i][j]=in.nextInt();}}boolean[][] visited=new boolean[n+2][m+2];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(graph[i][j]==1&&visited[i][j]==false){visited[i][j]=true;dfs(graph,visited,i,j);}}}System.out.println(ans);}private static int[][] dir={{0,1},{1,0},{-1,0},{0,-1}};public static void dfs(int[][] graph,boolean[][] visited,int x,int y){for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nexty<0||nextx>=graph.length||nexty>=graph[0].length)continue;if(graph[nextx][nexty]==0)ans++;if(graph[nextx][nexty]==1&&visited[nextx][nexty]==false){visited[nextx][nexty]=true;dfs(graph,visited,nextx,nexty);}}}
}

字符串接龙

题目描述

字典 strList 中从字符串 beginStr 和 endStr 的转换序列是一个按下述规格形成的序列:

序列中第一个字符串是 beginStr。

序列中最后一个字符串是 endStr。

每次转换只能改变一个位置的字符(例如 ftr 可以转化 fty ,但 ftr 不能转化 frx)。

转换过程中的中间字符串必须是字典 strList 中的字符串。

beginStr 和 endStr 不在 字典 strList 中

字符串中只有小写的26个字母

给你两个字符串 beginStr 和 endStr 和一个字典 strList,找到从 beginStr 到 endStr 的最短转换序列中的字符串数目。如果不存在这样的转换序列,返回 0。

输入描述

第一行包含一个整数 N,表示字典 strList 中的字符串数量。 第二行包含两个字符串,用空格隔开,分别代表 beginStr 和 endStr。 后续 N 行,每行一个字符串,代表 strList 中的字符串。

输出描述

输出一个整数,代表从 beginStr 转换到 endStr 需要的最短转换序列中的字符串数量。如果不存在这样的转换序列,则输出 0。

输入示例:

6
abc def
efc
dbc
ebc
dec
dfc
yhn

输出示例

4

提示信息

从 startStr 到 endStr,在 strList 中最短的路径为 abc -> dbc -> dec -> def,所以输出结果为 4,如图:

数据范围:

2 <= N <= 500

思路:

首先我们要解决两个问题:

1.图中的边是怎么来的?我们用26个英文字母替换当前字符串的每一个字符,看替换后是否在strList中出现过,如果出现过,那么这里就有一条边。

2.起点和终点的最短路径长度:

直接使用广搜法,只要搜到了终点(也就是endString),那么就一定是最短路径。这里如果用深搜法会比较麻烦,因为需要再到达终点的不同路径中选一条最短路径。

需要注意的是我们需要标记节点是否走过,这里使用set集合来检查会更快一点。

代码如下:

import java.util.*;public class Main{public static void main(String[] args){Scanner in=new Scanner(System.in);int n=in.nextInt();String begin=in.next();String end=in.next();List<String> list=new ArrayList<>();list.add(begin);list.add(end);for(int i=0;i<n;i++){list.add(in.next());}int ans=bfs(begin,end,list);System.out.println(ans);}public static int bfs(String begin,String end,List<String> list){int len=1;Set<String> set=new HashSet<>();//相当于visitedQueue<String> q=new LinkedList<>();q.offer(begin);q.offer(null);while(!q.isEmpty()){String tmp=q.poll();if(tmp==null){if(!q.isEmpty()){len++;q.offer(null);}continue;}set.add(tmp);char[] array=tmp.toCharArray();for(int i=0;i<array.length;i++){char old=array[i];for(char ch='a';ch<='z';ch++){array[i]=ch;String newString=new String(array);if(!set.contains(newString)&&list.contains(newString)){set.add(newString);q.offer(newString);if(newString.equals(end))return len+1;}}array[i]=old;}}return 0;}
}

有向图的完全联通

题目描述

给定一个有向图,包含 N 个节点,节点编号分别为 1,2,...,N。现从 1 号节点开始,如果可以从 1 号节点的边可以到达任何节点,则输出 1,否则输出 -1。

输入描述

第一行包含两个正整数,表示节点数量 N 和边的数量 K。 后续 K 行,每行两个正整数 s 和 t,表示从 s 节点有一条边单向连接到 t 节点。

输出描述

如果可以从 1 号节点的边可以到达任何节点,则输出 1,否则输出 -1。

输入示例

4 4
1 2
2 1
1 3
2 4

输出示例

1

提示信息

从 1 号节点可以到达任意节点,输出 1。

数据范围:

1 <= N <= 100;
1 <= K <= 2000。

思路:

深搜法,如果节点1可以到达节点2,继续看节点2能否到达其他节点,如果节点2能到达其他节点,说明节点1也可以到达这些节点,将这些节点都标记为true。最后遍历所有节点是否都标记为true,如果是的话输出1,否则输出-1。

代码如下:

import java.util.*;public class Main{public static void main(String[] args){Scanner in=new Scanner(System.in);int n=in.nextInt();int k=in.nextInt();int[][] graph=new int[n+1][n+1];for(int i=0;i<k;i++){int x=in.nextInt();int y=in.nextInt();graph[x][y]=1;}boolean[] visited=new boolean[n+1];visited[1]=true;dfs(graph,visited,1,n);for(int i=1;i<=n;i++){if(visited[i]==false){System.out.println(-1);return;}}System.out.println(1);}public static void dfs(int[][] graph,boolean[] visited,int x,int n){for(int j=1;j<=n;j++){if(graph[x][j]==1&&visited[j]==false){visited[j]=true;dfs(graph,visited,j,n);}}}
}

其实深搜广搜的难度并不在广搜深搜本身,而是如何应用深搜广搜去解决问题,要想明白这个逻辑。

http://www.lryc.cn/news/625756.html

相关文章:

  • BROADCHIP广芯电子在各类电子产品的方案与应用
  • 企业如何让内部视频仅限指定域名播放,确保视频不被泄露?
  • 2025年8月16日(星期六):雨骑古莲村游记
  • 机器人控制基础:运动控制中的串级pid原理以及实现方案(包含代码示例)
  • 学习笔记分享——基于STM32的平衡车项目
  • 8.19打卡 DAY 46 通道注意力(SE注意力)
  • RabbitMQ处理流程详解
  • docker回炉重造
  • 无畏契约手游上线!手机远控模拟器畅玩、抢先注册稀有ID!
  • 概率论基础教程第5章 连续型随机变量(一)
  • Flask 路由与视图函数绑定机制
  • 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET... 拒绝访问
  • 概率论基础教程第4章 随机变量(四)
  • Android Cordova 开发 - Cordova 嵌入 Android
  • GaussDB 中 alter default privileges 的使用示例
  • 从H.264到AV1:音视频技术演进与模块化SDK架构全解析
  • Meta首款AR眼镜Hypernova呼之欲出,苹果/微美全息投入显著抢滩市场新增长点!
  • 搭建最新--若依分布式spring cloudv3.6.6 前后端分离项目--步骤与记录常见的坑
  • 磨砂玻璃登录页面使用教程 v0.1.1
  • 可靠性测试:软件稳定性的守护者
  • t12 low power design: power plan脚本分享(4) power stripe
  • 9.Ansible管理大项目
  • MCP(模型上下文协议):是否是 AI 基础设施中缺失的标准?
  • Flink原理与实践:第一章大数据技术概述总结
  • Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
  • 构建自主企业:AgenticOps 的技术蓝图
  • VS Code 终端完全指南
  • Java 大视界 -- Java 大数据机器学习模型在自然语言处理中的多语言翻译与文化适应性优化
  • Transformer十问
  • Java试题-选择题(11)