华为2023.9.20笔试题目

华为2023.9.20笔试题目

下周华为面试,复盘下当时的笔试题目

题目1

描述 :某通信系统持续向外发送报文,使用数组nums保存n个最近发送的报文,用于在报文未达到对端的情况下重发。报文使用序号sn表示,序号sn按照报文发送顺序从小到大排序,相邻报文sn不完全连续且有可能相同。报文使用循环覆盖的方式保存,即nums数组填满后,从头开始保存新的报文。假设需要重发序号为sn的报文。请找出序号为sn的报文在数组中的开始位置和结束位置。
输入

  1. 第一行输入:数组nums的大小n,取值范围[010000]
  2. 第二行输入:数组中的所有报文的序号sn,sn取值范围[0,100000]
  3. 第三行输入:需要重发的报文序号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. 男同学只能将球传给男同学,不能传给女同学
  2. 球只能传给身边前后左右相邻的同学
  3. 如果游戏不能完成,返回-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写太折磨了

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值