华为OD机试 2024C卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
给定一个二维数组M行N列,二维数组里的数字代表图片的像素,为了简化问题,仅包含像素1和5两种像素,每种像素代表一个物体2个物体相邻的格子为边界,求像素1代表的物体的边界个数。
像素1代表的物体的边界指与像素5相邻的像素1的格子,边界相邻的属于同一个边界,相邻需要考虑8个方向(上,下,左,右,左上,左下,右上,右下)。
其他约束:地图规格约束为:
0<M<100
0<N<100
二、输入描述
第一行,行数M, 列数N
第二行开始,是M行N列的像素的二维数组,仅包含像素1和5
三、输出描述
像素1代表的物体的边界个数。如果没有边界输出0(比如只存在像素1,或者只存在像素5)。
1、输入
6 6
1 1 1 1 1 1
1 5 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 5
2、输出
2
四、解题思路
- 对于矩阵中的每个像素1,如果它的8个方向(上、下、左、右、左上、左下、右上、右下)中至少有一个方向有像素5,则该像素1是边界的一部分。
- 对于每个标记为边界的像素1,使用DFS来标记与之相连的所有边界像素1,以确保每个边界只被计数一次。使用一个二维数组 visited 来记录哪些像素已经被访问过。
- 初始化边界计数为0。遍历二维数组中的每个元素,每当找到一个未访问过的边界像素1时,对它执行DFS并增加边界计数。
- 在DFS中,从当前像素开始,检查所有8个可能的方向,对于每个方向,如果是像素1且未被访问过,则递归调用DFS。
- 输出最终的边界计数。
五、Java算法源码
这段代码实现了上述算法,通过深度优先搜索标记和计数所有边界像素,最终打印边界的数量。注意在大型输入和边缘情况下测试以确保代码的鲁棒性。
public class OdTest02 {private static final int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1};private static final int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1};public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int M = scanner.nextInt();int N = scanner.nextInt();int[][] grid = new int[M][N];boolean[][] visited = new boolean[M][N];// 读取像素数据for (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {grid[i][j] = scanner.nextInt();}}int boundaryCount = 0;// 遍历像素数组for (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {if (grid[i][j] == 1 && !visited[i][j] && isBoundary(grid, i, j, M, N)) {// 执行DFS以标记所有相连的边界像素dfs(grid, visited, i, j, M, N);boundaryCount++;}}}System.out.println(boundaryCount);scanner.close();}// 判断是否为边界private static boolean isBoundary(int[][] grid, int x, int y, int M, int N) {for (int d = 0; d < 8; d++) {int nx = x + dx[d];int ny = y + dy[d];if (nx >= 0 && nx < M && ny >= 0 && ny < N && grid[nx][ny] == 5) {return true;}}return false;}// 深度优先搜索private static void dfs(int[][] grid, boolean[][] visited, int x, int y, int M, int N) {if (x < 0 || x >= M || y < 0 || y >= N || visited[x][y] || grid[x][y] != 1) {return;}visited[x][y] = true;if (!isBoundary(grid, x, y, M, N)) {return;}for (int d = 0; d < 8; d++) {int nx = x + dx[d];int ny = y + dy[d];dfs(grid, visited, nx, ny, M, N);}}
}
六、效果展示
1、输入
6 6
1 1 1 1 1 1
1 5 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 5 1
1 1 1 1 1 1
2、输出
1
3、说明
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。