这道华为OD机考题考察的是图论中的连通域问题在实际场景中的应用。题目描述了一个由0和1组成的二维矩阵,其中1代表服务器节点,0代表空白位置。如果两个服务器节点在水平或垂直方向相邻,则认为它们属于同一个网络。我们需要计算出矩阵中最大的服务器网络包含的节点数量。
这类问题在分布式系统部署、云计算资源调度、物联网设备管理中非常常见。比如在数据中心规划时,工程师需要评估服务器集群的冗余性和容错能力;在5G基站部署时,需要分析信号覆盖区域的连续性。这道题将实际工程问题抽象为算法题,非常考验候选人的问题建模能力和基础算法功底。
我们可以将输入矩阵看作一个无向图:
常见的解决方案有三种:
对于机考场景,DFS/BFS的时间复杂度都是O(mn),空间复杂度最坏也是O(mn)。并查集虽然理论复杂度更好,但实现较复杂,在二维矩阵问题上优势不明显。因此推荐使用DFS或BFS。
提示:在实际机考中,DFS的递归实现代码更简洁,但需要注意Python的递归深度限制;BFS的迭代实现更安全,适合大规模数据。
java复制import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] matrix = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = sc.nextInt();
}
}
System.out.println(maxNetwork(matrix));
}
static int maxNetwork(int[][] grid) {
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
max = Math.max(max, dfs(grid, i, j));
}
}
}
return max;
}
static int dfs(int[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] != 1) {
return 0;
}
grid[i][j] = 0; // 标记为已访问
return 1 + dfs(grid, i+1, j) + dfs(grid, i-1, j)
+ dfs(grid, i, j+1) + dfs(grid, i, j-1);
}
}
关键点说明:
python复制def max_network(grid):
max_count = 0
m, n = len(grid), len(grid[0])
def dfs(i, j):
if 0 <= i < m and 0 <= j < n and grid[i][j] == 1:
grid[i][j] = 0
return 1 + dfs(i+1,j) + dfs(i-1,j) + dfs(i,j+1) + dfs(i,j-1)
return 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
max_count = max(max_count, dfs(i, j))
return max_count
# 示例输入
grid = [
[1,0,0,1,0],
[0,0,1,1,0],
[0,1,0,0,0],
[0,0,0,0,1]
]
print(max_network(grid)) # 输出应为4
Python实现特点:
javascript复制function maxNetwork(grid) {
let max = 0;
const m = grid.length, n = grid[0].length;
function dfs(i, j) {
if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] !== 1) {
return 0;
}
grid[i][j] = 0;
return 1 + dfs(i+1,j) + dfs(i-1,j) + dfs(i,j+1) + dfs(i,j-1);
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === 1) {
max = Math.max(max, dfs(i, j));
}
}
}
return max;
}
// 测试用例
const grid = [
[1,0,0,1,0],
[0,0,1,1,0],
[0,1,0,0,0],
[0,0,0,0,1]
];
console.log(maxNetwork(grid)); // 4
JS实现注意:
go复制package main
import "fmt"
func maxNetwork(grid [][]int) int {
max := 0
m, n := len(grid), len(grid[0])
var dfs func(int, int) int
dfs = func(i, j int) int {
if i < 0 || j < 0 || i >= m || j >= n || grid[i][j] != 1 {
return 0
}
grid[i][j] = 0
return 1 + dfs(i+1,j) + dfs(i-1,j) + dfs(i,j+1) + dfs(i,j-1)
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
if count := dfs(i, j); count > max {
max = count
}
}
}
}
return max
}
func main() {
grid := [][]int{
{1,0,0,1,0},
{0,0,1,1,0},
{0,1,0,0,0},
{0,0,0,0,1},
}
fmt.Println(maxNetwork(grid)) // 输出4
}
Go语言特点:
cpp复制#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int dfs(vector<vector<int>>& grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] != 1) {
return 0;
}
grid[i][j] = 0;
return 1 + dfs(grid, i+1, j) + dfs(grid, i-1, j)
+ dfs(grid, i, j+1) + dfs(grid, i, j-1);
}
int maxNetwork(vector<vector<int>>& grid) {
int max = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1) {
max = std::max(max, dfs(grid, i, j));
}
}
}
return max;
}
int main() {
vector<vector<int>> grid = {
{1,0,0,1,0},
{0,0,1,1,0},
{0,1,0,0,0},
{0,0,0,0,1}
};
cout << maxNetwork(grid) << endl; // 输出4
return 0;
}
C++注意事项:
c复制#include <stdio.h>
int dfs(int** grid, int gridSize, int* gridColSize, int i, int j) {
if (i < 0 || j < 0 || i >= gridSize || j >= gridColSize[0] || grid[i][j] != 1) {
return 0;
}
grid[i][j] = 0;
return 1 + dfs(grid, gridSize, gridColSize, i+1, j)
+ dfs(grid, gridSize, gridColSize, i-1, j)
+ dfs(grid, gridSize, gridColSize, i, j+1)
+ dfs(grid, gridSize, gridColSize, i, j-1);
}
int maxNetwork(int** grid, int gridSize, int* gridColSize) {
int max = 0;
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridColSize[i]; j++) {
if (grid[i][j] == 1) {
int count = dfs(grid, gridSize, gridColSize, i, j);
if (count > max) max = count;
}
}
}
return max;
}
int main() {
int row1[] = {1,0,0,1,0};
int row2[] = {0,0,1,1,0};
int row3[] = {0,1,0,0,0};
int row4[] = {0,0,0,0,1};
int* grid[] = {row1, row2, row3, row4};
int gridSize = 4;
int gridColSize[] = {5,5,5,5};
printf("%d\n", maxNetwork(grid, gridSize, gridColSize)); // 输出4
return 0;
}
C语言特点:
输入处理优化:在机考环境中,大数据量输入时使用快速的IO方法
空间优化:如果不允许修改原矩阵,可以额外使用visited数组记录访问状态
迭代式DFS:使用栈实现DFS避免递归深度限制
python复制def dfs_iterative(grid, i, j):
stack = [(i, j)]
count = 0
while stack:
x, y = stack.pop()
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] == 1:
grid[x][y] = 0
count += 1
stack.append((x+1, y))
stack.append((x-1, y))
stack.append((x, y+1))
stack.append((x, y-1))
return count
统计网络数量:计算矩阵中总共有多少个独立的服务器网络
八连通问题:对角线相邻的服务器也算作同一网络
加权网络:每个服务器有不同的权重,求最大权重和网络
动态连接问题:支持动态添加/删除服务器节点
环境准备:
编码规范:
调试技巧:
重要提示:在机考中,先确保基本功能正确,再考虑优化。部分正确比超时但未完成的代码得分更高。
云计算资源调度:
物联网设备管理:
图像处理:
并行算法:
分布式算法:
机器学习应用:
在实际开发中遇到类似问题时,建议先分析问题规模和要求。对于小规模数据,简单的DFS/BFS即可;对于大规模分布式场景,可能需要考虑更复杂的并行算法或使用专门的图计算框架。