华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
有一个二维的天线矩阵,每根天线可以向其他天线发射信号,也能接收其他天线发射的信号。为了简化起见,我们约定每根天线只能向东和向南发射信号,换言之,每根天线只能接收到东侧或南侧的信号。
每根天线有自己的高度值anth,每根天线的高度存储在一个二维数组Q中,各个天线的位置用[r, c]表示,r代表天线的行位置(从0开始编号),c代表天线的列位置(从0开始编号)。
在某一方向(东向或南向),某根天线可以收到其他天线的信号(也可能收不到任何其他天线的信号),对任一天线X和天线Y,天线X能接收到天线Y信号的条件是:
天线X在天线Y的东边或南边
天线X和天线Y之间的其他天线的高度都低于天线X和天线Y,或天线X和天线Y之间无其他天线,即无遮挡。
如下面示意:
在天线矩阵中的第0行上:
天线[0, 0]接收不到任何其他天线的信号;
天线[0, 1]可以接收到天线[0, 0]的信号;
天线[0, 2]可以接收到天线[0, 1]的信号;
天线[0, 3]可以接收到天线[0, 1]和天线[0, 2]的信号;
天线[0, 4]可以接收到天线[0, 3]的信号;
天线[0, 5]可以接收到天线[0, 4]的信号。
在天线的第0列上:
天线[0, 0]接收不到任何其他天线的信号;
天线[1, 0]可以接收到天线[0, 0]的信号;
天线[2, 0]可以接收到天线[1, 0]的信号;
天线[3, 0]可以接收到天线[2, 0]和天线[0, 0]的信号;
天线[4, 0]可以接收到天线[3, 0]的信号;
天线[5, 0]可以接收到天线[3, 0]和天线[4, 0]的信号。
给一个m行n列的矩阵(二维矩阵),矩阵存储着天线的高度,求出每根天线可以接收到多少根其他天线的信号,结果输出到m行n列的矩阵(二维矩阵)中。
二、输入描述
输入为1个m行n列的矩阵(二维矩阵)anth[m][n],矩阵存储着天线的高度,高度[anth[r][c]]为大于0的整数。
第一行为输入矩阵的行数和列数,如:
m n
第二行为输入矩阵的元素值,按行输入,如:
anth[0][0] anth[0][1] … anth[0][n-1]
anth[1][0] anth[1][1] … anth[1][n-1]
…
anth[m-1][0] … anth[m-1][n-1]
三、输出描述
输出一个m行n列的矩阵(二维数组)ret[m][n],矩阵存储每根天线能接收到多少根其他天线的信号,根数为ret[r][c]。
第一行为输出矩阵的行数和列数,如:
m n
第二行为输出矩阵的元素值,按行输出,如:
ret[0][0] ret[0][1] … ret[0][n-1]
ret[1][0] ret[1][1] … ret[1][n-1]
…
ret[m-1][0] … ret[m-1][n-1]
备注
1 ≤ m ≤ 500
1 ≤ n ≤ 500
0 < anth[r][c] < 10^5
四、测试用例
测试用例1:
1、输入
1 6
2 4 1 5 3 3
2、输出
1 6
0 1 1 2 1 1
3、说明
输入为1行6列的天线矩阵的高度值
[2 4 1 5 3 3]
输出为1行6列的结果矩阵
[0 1 1 2 1 1]
测试用例2:
1、输入
2 6
2 5 4 3 2 8 9 7 5 10 10 3
2、输出
2 6
0 1 1 1 1 4
1 2 2 4 2 2
3、说明
输入为2行6列的天线矩阵高度值
[2 5 4 3 2 8]
[9 7 5 10 10 3]
输出为2行6列的结果矩阵
[0 1 1 1 1 4]
[1 2 2 4 2 2]
五、解题思路
1、问题理解
给定一个m x n的二维矩阵anth,表示天线的高度。每根天线可以向东(右)和向南(下)发射信号。因此,每根天线只能接收到来自西(左)或北(上)的信号。对于任意两个天线Y和X,天线X可以接收到天线Y的信号的条件是:
- Y位于X的西边或北边。
- 在Y和X之间的所有天线(沿行或列)都比Y和X的高度小,或者Y和X之间没有其他天线(即直接相邻)。
2、具体步骤
- 输入读取:
- 使用Scanner读取矩阵的行数m和列数n。
- 读取矩阵anth的元素值。
- 初始化结果矩阵:
- 创建一个m x n的结果矩阵ret,用于存储每根天线可以接收到的信号数量。
- 遍历每个天线:
- 对于每根天线X(位置[r][c]),分别向西(同一行,列索引减小)和向北(同一列,行索引减小)查找所有可能的天线Y。
- 对于每个方向,检查Y到X之间是否满足条件:
- 如果Y和X之间没有其他天线,则Y可以向X发送信号。
- 如果Y和X之间有天线,所有中间天线的高度都小于Y和X的最小高度,则Y可以向X发送信号。
- 将满足条件的Y数量累加到ret[r][c]中。
- 输出结果:
- 按照题目要求的格式输出结果矩阵ret。
六、Python算法源码
# AntennaSignalReceiver.py
# 定义天线信号接收者问题的解决方案
# 导入必要的模块
import sys
def main():
# 读取输入的行数m和列数n
try:
m, n = map(int, sys.stdin.readline().split())
except:
# 如果读取失败,退出程序
print("输入格式错误,无法读取行数和列数。")
return
# 初始化天线高度矩阵anth
anth = []
for _ in range(m):
try:
row = list(map(int, sys.stdin.readline().split()))
if len(row) != n:
print(f"输入的列数与预期不符,预期{n}列,实际{len(row)}列。")
return
anth.append(row)
except:
print("输入格式错误,无法读取天线高度。")
return
# 初始化结果矩阵ret,所有元素初始化为0
ret = [[0 for _ in range(n)] for _ in range(m)]
# 遍历每个天线位置
for r in range(m):
for c in range(n):
count = 0 # 当前天线可以接收到的信号数量
# 向西方向查找(同一行,列索引减小)
for yc in range(c - 1, -1, -1):
can_receive = True # 标记是否可以接收来自该天线的信号
# 计算当前天线和候选天线的最小高度
min_height = min(anth[r][c], anth[r][yc])
# 检查候选天线和当前天线之间的所有天线
for kc in range(yc + 1, c):
if anth[r][kc] >= min_height:
can_receive = False # 存在高度不满足条件的天线
break
if can_receive:
count += 1 # 可以接收来自该天线的信号
# 向北方向查找(同一列,行索引减小)
for yr in range(r - 1, -1, -1):
can_receive = True # 标记是否可以接收来自该天线的信号
# 计算当前天线和候选天线的最小高度
min_height = min(anth[r][c], anth[yr][c])
# 检查候选天线和当前天线之间的所有天线
for kr in range(yr + 1, r):
if anth[kr][c] >= min_height:
can_receive = False # 存在高度不满足条件的天线
break
if can_receive:
count += 1 # 可以接收来自该天线的信号
# 将计数结果存入结果矩阵ret
ret[r][c] = count
# 输出结果矩阵的行数和列数
print(f"{m} {n}")
# 输出结果矩阵的元素值,按行输出
for row in ret:
print(' '.join(map(str, row)))
if __name__ == "__main__":
main()
七、JavaScript算法源码
// AntennaSignalReceiver.js
// 定义天线信号接收者问题的解决方案
// 使用Node.js的readline模块读取输入
const readline = require('readline');
// 创建接口实例
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 初始化输入数据存储
let inputLines = [];
let m = 0, n = 0;
let currentRow = 0;
rl.on('line', (line) => {
if (line.trim() === '') return; // 忽略空行
inputLines.push(line.trim());
// 读取行数和列数
if (inputLines.length === 1) {
const dimensions = line.trim().split(' ').map(Number);
m = dimensions[0];
n = dimensions[1];
}
// 读取天线高度矩阵
if (inputLines.length > 1 && inputLines.length <= m +1) {
currentRow++;
}
// 当所有输入读取完毕,开始处理
if (inputLines.length === m +1) {
rl.close();
}
}).on('close', () => {
// 解析天线高度矩阵
let anth = [];
for (let r =1; r <= m; r++) {
let row = inputLines[r].split(' ').map(Number);
anth.push(row);
}
// 初始化结果矩阵ret,所有元素初始化为0
let ret = Array.from({length: m}, () => Array(n).fill(0));
// 遍历每个天线位置
for (let r =0; r < m; r++) {
for (let c =0; c < n; c++) {
let count =0; // 当前天线可以接收到的信号数量
// 向西方向查找(同一行,列索引减小)
for (let yc = c -1; yc >=0; yc--) {
let canReceive = true; // 标记是否可以接收来自该天线的信号
let minHeight = Math.min(anth[r][c], anth[r][yc]);
// 检查候选天线和当前天线之间的所有天线
for (let kc = yc +1; kc < c; kc++) {
if (anth[r][kc] >= minHeight) {
canReceive = false; // 存在高度不满足条件的天线
break;
}
}
if (canReceive) {
count +=1; // 可以接收来自该天线的信号
}
}
// 向北方向查找(同一列,行索引减小)
for (let yr = r -1; yr >=0; yr--) {
let canReceive = true; // 标记是否可以接收来自该天线的信号
let minHeight = Math.min(anth[r][c], anth[yr][c]);
// 检查候选天线和当前天线之间的所有天线
for (let kr = yr +1; kr < r; kr++) {
if (anth[kr][c] >= minHeight) {
canReceive = false; // 存在高度不满足条件的天线
break;
}
}
if (canReceive) {
count +=1; // 可以接收来自该天线的信号
}
}
// 将计数结果存入结果矩阵ret
ret[r][c] = count;
}
}
// 输出结果矩阵的行数和列数
console.log(`${m} ${n}`);
// 输出结果矩阵的元素值,按行输出
for (let r =0; r < m; r++) {
console.log(ret[r].join(' '));
}
});
八、C算法源码
/* AntennaSignalReceiver.c
* 定义天线信号接收者问题的解决方案
*/
#include <stdio.h>
#include <stdlib.h>
int main() {
int m, n;
// 读取矩阵的行数m和列数n
if (scanf("%d %d", &m, &n) != 2) {
printf("输入格式错误,无法读取行数和列数。\n");
return 1;
}
// 动态分配天线高度矩阵anth
int **anth = (int **)malloc(m * sizeof(int *));
for (int r = 0; r < m; r++) {
anth[r] = (int *)malloc(n * sizeof(int));
for (int c = 0; c < n; c++) {
if (scanf("%d", &anth[r][c]) != 1) {
printf("输入格式错误,无法读取天线高度。\n");
// 释放已分配的内存
for (int i = 0; i <= r; i++) {
free(anth[i]);
}
free(anth);
return 1;
}
}
}
// 动态分配结果矩阵ret,初始化为0
int **ret = (int **)malloc(m * sizeof(int *));
for (int r = 0; r < m; r++) {
ret[r] = (int *)calloc(n, sizeof(int));
}
// 遍历每个天线位置
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) {
int count = 0; // 当前天线可以接收到的信号数量
// 向西方向查找(同一行,列索引减小)
for (int yc = c -1; yc >=0; yc--) {
int can_receive = 1; // 标记是否可以接收来自该天线的信号
int min_height = (anth[r][c] < anth[r][yc]) ? anth[r][c] : anth[r][yc];
// 检查候选天线和当前天线之间的所有天线
for (int kc = yc +1; kc < c; kc++) {
if (anth[r][kc] >= min_height) {
can_receive = 0; // 存在高度不满足条件的天线
break;
}
}
if (can_receive) {
count++; // 可以接收来自该天线的信号
}
}
// 向北方向查找(同一列,行索引减小)
for (int yr = r -1; yr >=0; yr--) {
int can_receive = 1; // 标记是否可以接收来自该天线的信号
int min_height = (anth[r][c] < anth[yr][c]) ? anth[r][c] : anth[yr][c];
// 检查候选天线和当前天线之间的所有天线
for (int kr = yr +1; kr < r; kr++) {
if (anth[kr][c] >= min_height) {
can_receive = 0; // 存在高度不满足条件的天线
break;
}
}
if (can_receive) {
count++; // 可以接收来自该天线的信号
}
}
// 将计数结果存入结果矩阵ret
ret[r][c] = count;
}
}
// 输出结果矩阵的行数和列数
printf("%d %d\n", m, n);
// 输出结果矩阵的元素值,按行输出
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) {
printf("%d", ret[r][c]);
if (c != n -1) {
printf(" ");
}
}
printf("\n");
}
// 释放动态分配的内存
for (int r = 0; r < m; r++) {
free(anth[r]);
free(ret[r]);
}
free(anth);
free(ret);
return 0;
}
九、C++算法源码
// AntennaSignalReceiver.cpp
// 定义天线信号接收者问题的解决方案
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int m, n;
// 读取矩阵的行数m和列数n
cin >> m >> n;
// 初始化天线高度矩阵anth
vector<vector<int>> anth(m, vector<int>(n));
for(int r =0; r < m; r++) {
for(int c =0; c < n; c++) {
cin >> anth[r][c];
}
}
// 初始化结果矩阵ret,所有元素初始化为0
vector<vector<int>> ret(m, vector<int>(n, 0));
// 遍历每个天线位置
for(int r =0; r < m; r++) {
for(int c =0; c < n; c++) {
int count =0; // 当前天线可以接收到的信号数量
// 向西方向查找(同一行,列索引减小)
for(int yc = c -1; yc >=0; yc--) {
bool can_receive = true; // 标记是否可以接收来自该天线的信号
int min_height = min(anth[r][c], anth[r][yc]);
// 检查候选天线和当前天线之间的所有天线
for(int kc = yc +1; kc < c; kc++) {
if(anth[r][kc] >= min_height) {
can_receive = false; // 存在高度不满足条件的天线
break;
}
}
if(can_receive) {
count++; // 可以接收来自该天线的信号
}
}
// 向北方向查找(同一列,行索引减小)
for(int yr = r -1; yr >=0; yr--) {
bool can_receive = true; // 标记是否可以接收来自该天线的信号
int min_height = min(anth[r][c], anth[yr][c]);
// 检查候选天线和当前天线之间的所有天线
for(int kr = yr +1; kr < r; kr++) {
if(anth[kr][c] >= min_height) {
can_receive = false; // 存在高度不满足条件的天线
break;
}
}
if(can_receive) {
count++; // 可以接收来自该天线的信号
}
}
// 将计数结果存入结果矩阵ret
ret[r][c] = count;
}
}
// 输出结果矩阵的行数和列数
cout << m << " " << n << "\n";
// 输出结果矩阵的元素值,按行输出
for(int r =0; r < m; r++) {
for(int c =0; c < n; c++) {
cout << ret[r][c];
if(c != n -1) {
cout << " ";
}
}
cout << "\n";
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。