华为2023.9.20笔试题目
下周华为面试,复盘下当时的笔试题目
题目1
描述 :某通信系统持续向外发送报文,使用数组nums保存n个最近发送的报文,用于在报文未达到对端的情况下重发。报文使用序号sn表示,序号sn按照报文发送顺序从小到大排序,相邻报文sn不完全连续且有可能相同。报文使用循环覆盖的方式保存,即nums数组填满后,从头开始保存新的报文。假设需要重发序号为sn的报文。请找出序号为sn的报文在数组中的开始位置和结束位置。
输入:
- 第一行输入:数组nums的大小n,取值范围[010000]
- 第二行输入:数组中的所有报文的序号sn,sn取值范围[0,100000]
- 第三行输入:需要重发的报文序号sn,取值范围[0,1000001
输出:
start end
说明: start和end代表需要重发的报文序号sn在数组中的起始下标和结束下标
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, sn;
cin >> n;
vector<int> nums(n, -1);
for(int i = 0; i < n; i++) {
cin >> nums[i];
}
cin >> sn;
/*
要点1:找到所有报文最小的sn
*/
int min = 0, min_sn = nums[min];
for(int i = 0; i < n; i++) {
if(nums[i] < min_sn) {
min_sn = nums[i];
min = i;
}
}
/*
要点2:从最小的sn开始遍历整个数组
*/
int start = -1, end = -1;
for(int i = 0; i < n ; i++) {
int index = (min + i) % n;
if(nums[index] == sn) {
if(start == -1) {
start = index;
end = index;
} else {
end = index;
}
}
}
cout << start << " " << end << endl;
}
题目2
描述:班级组织传球活动,男女同学随机排成m行n列队伍,第一列中的任意个男同学都可以作为传球的起点,要求最终将球传到最后一列的任意一个男同学手里,求所有能够完成任务的传球路线中的最优路线 (传球次数最少的路线)的传球次数。
传球规则:
- 男同学只能将球传给男同学,不能传给女同学
- 球只能传给身边前后左右相邻的同学
- 如果游戏不能完成,返回-1
输入:班级同学随机排成的m行n列队伍,1代表男同学,0代表女同学输入第一行包含两个用空格分开的整数m [1,30]和n [1,30],表示m行n列的队伍;接下来是m行每行包含n个用空格分开的整数1或0
输出:最优路线的传球次数 (最少传球次数)
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int main() {
int m, n;
cin >> m >> n; //从输入中读取两个整数m和n
vector<vector<int>> mat(m, vector<int>(n)); // 创建一个m*n的二维向量mat
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
cin >> mat[i][j]; // 从输入中读取mat的每个元素
}
}
queue<pair<int, int>> q; // 创建一个队列q,用于存储坐标对
vector<vector<int>> dist(m, vector<int>(n, -1)); // 创建一个m*n的二维向量dist,初始值为-1
for(int i = 0; i < m; i++) {
if(mat[i][0] == 1) { // 如果mat的第一列中有元素值为1
q.push({i, 0}); // 将该元素的坐标加入队列q
dist[i][0] = 0; // 将dist中对应的元素值设为0
}
}
vector<pair<int, int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // 创建一个向量dirs,用于表示四个方向
while(!q.empty()) { // 当队列q不为空时
pair<int, int> p = q.front(); q.pop(); // 取出队列q的第一个元素,并将其从队列中移除
for(pair<int, int> dir : dirs) { // 遍历四个方向
int ni = p.first + dir.first, nj = p.second + dir.second; // 计算新的坐标
if(ni >= 0 && ni < m && nj >= 0 && nj < n && mat[ni][nj] == 1 && dist[ni][nj] == -1) { // 如果新的坐标在mat内,且对应的元素值为1,且在dist中对应的元素值为-1
dist[ni][nj] = dist[p.first][p.second] + 1; // 更新dist中对应的元素值
q.push({ni, nj}); // 将新的坐标加入队列q
}
}
}
int minDist = INT_MAX; // 创建一个变量minDist,初始值为INT_MAX
for(int i = 0; i < m; i++)
if(dist[i][n-1] != -1) // 如果dist的最后一列中有元素值不为-1
minDist = min(minDist, dist[i][n-1]); // 更新minDist的值
if(minDist == INT_MAX) minDist = -1; // 如果minDist的值仍为INT_MAX,将其设为-1
cout << minDist << endl; // 输出minDist的值
return 0;
}
题目3
emmmmm感觉有点恶心,不想复盘(用cpp写太折磨了