hwod机考练习

文章讲述了作者在编程挑战中遇到的四个问题,涉及字符串中整数的最小和计算、满足条件的最长子串长度、字符串分割和动态规划解决玩牌高手问题。展示了使用BigInteger处理大整数和数据结构如栈、队列和并查集的实践应用。

不一定正确,都是自己凭感觉写的辣鸡代码

Day 1

题目详情 - 求字符串中所有整数的最小和 - Hydro

评测结果两个运行时错误,别的用例都过了,看不到用例详情不知道哪里写错了,先不管了就这样吧

估计是因为没用BigInteger,题目没说数字范围

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
  }

  static void getResult(String s) {
    // int res = 0;
    BigInteger res = new BigInteger("0");
    char[] chars = s.toCharArray();
    int i = 0;
    while (i < chars.length) {
      char c = chars[i];
      if (isNum(c)) {
        int j = i;
        for (; j < chars.length && isNum(chars[j]); j++) {
          // res += Integer.parseInt(String.valueOf(chars[j]));
          // 用BigInteger!!
          res = res.add(new BigInteger(String.valueOf(chars[j])));
        }
        i = j;
        continue;
      }
      if (c == '-') {
        int j = i + 1;
        if (j > chars.length - 1) break;
        for (; j < chars.length && isNum(chars[j]); j++) {}
        if (j > i + 1) {
          String subString = s.substring(i + 1, j);
          // int numberToDecrease = Integer.parseInt(subString);
          // res -= numberToDecrease;
          // 用BigInteger!!
          res = res.subtract(new BigInteger(subString));
          i = j;
        } else i++;
        continue;
      }
      i++;
    }
    System.out.println(res);
  }

  static boolean isNum(char c) {
    return c >= '0' && c <= '9';
  }
}

Day 2

题目详情 - 求满足条件的最长子串的长度 - Hydro

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
  }

  static void getResult(String input) {
    char[] chars = input.toCharArray();
    int length = 0;
    for (int i = 0; i < chars.length; i++) {
      char c = chars[i];
      if (isNum(c)) {
        int letterCount = 0;
        int j = i;
        for (; j < chars.length; j++) {
          if (!isNum(chars[j])) letterCount++;
          if (letterCount > 1) break;
        }
        if (j > i) {
          if (letterCount > 0) length = Math.max(length, j - i);
          else if (i > 0 && !isNum(chars[i - 1])) length = Math.max(length, j - i + 1);
        }
      }
    }
    System.out.println(length == 0 ? -1 : length);
  }

  static boolean isNum(char c) {
    return c >= '0' && c <= '9';
  }
}

Day 3

题目详情 - 字符串分割(二) - Hydro

其实可以滑动窗口,自己只想到了暴力解

public class Main {
  static final int CHAR_OFFSET = 'a' - 'A';

  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int k = scanner.nextInt();
    String input = scanner.next();
    scanner.close();

    String[] split = input.split("-");
    StringBuilder sb = new StringBuilder();
    StringBuilder head = new StringBuilder(split[0]);
    for (int i = 1; i < split.length; i++) {
      sb.append(split[i]);
    }
    int count = 0;
    for (int i = 0, j = 0; i < sb.length(); i++) {
      count++;
      if (count == k) {
        transform(sb, j, i + 1);
        if (i < sb.length() - 1) sb.insert(++i, '-');
        j = i;
        count = 0;
      } else if (i == sb.length() - 1) {
        transform(sb, j, i + 1);
      }
    }
    if (sb.length() > 0) head.append('-').append(sb);
    System.out.println(head);
  }

  static void transform(StringBuilder sb, int start, int end) {
    int upperCount = 0, lowerCount = 0;
    ArrayList<Integer> upperIndices = new ArrayList<>();
    ArrayList<Integer> lowerIndices = new ArrayList<>();
    for (int i = start; i < end; i++) {
      char c = sb.charAt(i);
      if (c >= 'A' && c <= 'Z') { // uppercase
         upperCount++;
         upperIndices.add(i);
      }
      if (c >= 'a' && c <= 'z') { // lowercase
        lowerCount++;
        lowerIndices.add(i);
      }
    }
    if (upperCount > lowerCount) {
      lowerIndices.forEach(i -> sb.setCharAt(i, (char) (sb.charAt(i) - CHAR_OFFSET)));
    }
    if (upperCount < lowerCount) {
      upperIndices.forEach(i -> sb.setCharAt(i, (char) (sb.charAt(i) + CHAR_OFFSET)));
    }
  }
}

题目详情 - 玩牌高手 - Hydro

动态规划

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
    scanner.close();
  }

  static void getResult(String input) {
    String[] nums = input.split(",");
    int[] max = new int[nums.length];
    max[0] = Math.max(Integer.valueOf(nums[0]), 0);
    for (int i = 1; i < nums.length; i++) {
      max[i] = Math.max(max[i - 1] + Integer.valueOf(nums[i]), i <= 2 ? 0 : max[i - 3]);
    }
    System.out.println(max[max.length - 1]);
  }
}

题目详情 - 欢乐的周末 - Hydro

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int height = scanner.nextInt();
    int width = scanner.nextInt();
    // 填充矩阵
    int[][] matrix = new int[height][width];
    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        matrix[i][j] = scanner.nextInt();
      }
    }
    scanner.close();
    
    // 用于便捷计算任意一点朝上/下/左/右移动后的坐标
    int[][] offsets = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} };
    // 华为二人所在坐标
    List<Integer> huawei = new ArrayList<>();
    // 馆子坐标
    List<Integer> joints = new ArrayList<>();
    // 并查集,里面放矩阵中各点的坐标的整数表示
    UnionFind unionFind = new UnionFind(width * height);
   
    // 遍历矩阵 
    for (int i = 0; i < matrix.length; i++) {
      for (int j = 0; j < matrix[i].length; j++) {
        int n = matrix[i][j];
        if (n == 1) continue; // 遇到障碍物跳过
        int pos = j + i * width; // 二维坐标转为一个整数,作为存在于并查集中的位置
        if (n == 2) huawei.add(pos);
        if (n == 3) joints.add(pos);
        // 对于矩阵中任意一点,检查它与它上下左右各点的连通性
        for (int[] offset : offsets) {
          int newI = i + offset[0];
          int newJ = j + offset[1];
          if (newI >= 0 && newJ >=0 && newI < matrix.length && newJ < matrix[newI].length) {
            // 若上/下/左/右点的坐标合法,且与原点连通(值不为1),就在并查集中将其与原点融合
            if (matrix[newI][newJ] != 1) {
              int newPos = newJ + newI * width;
              unionFind.union(newPos, pos);
            }
          }
        }
      }
    }

    // 华为两人若不连通说明吃不到一块去,return
    if (!unionFind.isSameRoot(huawei.get(0), huawei.get(1))) {
      System.out.println(0);
      return;
    }

    int sum = 0;

    // 遍历馆子,如果馆子跟华为其中一人联通说明能吃饭,加一
    for (int pos : joints) {
      if (unionFind.isSameRoot(pos, huawei.get(0))) sum++;
    }

    System.out.println(sum);
  }

  static final class UnionFind {
    int[] arr;
    public UnionFind(int length) {
      arr = new int[length];
      for (int i = 0; i < length; i++) arr[i] = i;
    }

    public int findRoot(int e) {
      int root = arr[e];
      if (arr[root] != root) {
        arr[root] = findRoot(root);
        return arr[root];
      }
      return root;
    }

    public void union(int a, int b) {
      int rootA = findRoot(a);
      int rootB = findRoot(b);
      if (rootA != rootB) arr[rootA] = rootB;
    }

    public boolean isSameRoot(int a, int b) {
      return findRoot(a) == findRoot(b);
    }
  }
}

Day 4

题目详情 - 转盘寿司 - Hydro

public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);
  String line = scanner.nextLine();
  scanner.close();
  // 栈,存储{ 下标, 数值 }
  Deque<int[]> stack = new LinkedList<>();
  String[] split = line.split(" ");
  int leng = split.length;
  List<Integer> nums = Arrays.stream(split).map(Integer::valueOf).collect(Collectors.toList());
  // map存已经被处理过的数字,键是下标,值是处理后的数值
  Map<Integer, Integer> map = new HashMap<>();
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < leng; j++) {
      int curr = nums.get(j);
      // 若当前值比栈顶值小,栈顶值出栈,并将值与当前值相加,存到map,循环这一过程直到栈顶值大于等于当前值或者栈空
      while (!stack.isEmpty() && curr < stack.peek()[1]) {
        // record: { index, value }
        int[] record = stack.pop();
        map.put(record[0], record[1] + curr);
      }
      // 已经被处理过的数字就不入栈了
      if (!map.containsKey(j)) stack.push(new int[]{ j, curr });
    }
  }
  map.forEach(nums::set);
  System.out.println(nums.stream().map(String::valueOf).collect(Collectors.joining(" ")));
}

<think>嗯,用户想收集和整理华为OD机考的试题,归纳不同版本的题目内容。首先,我需要明确用户的具体需求是什么。可能用户正在准备参加华为OD的机考,或者想帮助他人整理资料。不管怎样,整理试题需要有系统的方法,否则容易混乱。 首先,用户提到的“试题整理方法”和“归纳技巧”是关键。我得考虑如何高效地收集试题。可能来源包括网络论坛、社交媒体群组、备考平台,或者官方发布的样题。例如,参考引用中提到的华为OD机试作弊、难度等问题,说明用户可能担心资料的准确性和完整性,所以需要验证试题的真实性。 然后是分类方法。题目可能分为算法数据结构、编程题等。比如快速排序、动态规划这些算法题常见,字符串处理、数组操作也是高频考点。用户需要按题型、难度或知识点来分类,这样复习起来更有针对性。 接下来是版本差异。不同时间段的试题可能有变化,比如2023年新增了某些题型,或者调整了难度。需要对比不同年份的题目,找出趋势,比如是否增加了对特定算法的考察频率。 在归纳技巧方面,建立结构化数据库可能有用,用Excel或Notion管理题目信息。同时,分析高频考点,比如二叉树遍历、链表操作等,帮助用户重点复习。还要注意题目变体,同一题目的不同描述或输入输出变化,这能帮助用户适应题目的灵活性。 用户可能遇到的挑战包括资料分散、真伪难辨,以及版本更新带来的变化。所以需要建议用户多渠道收集,交叉验证,并且定期更新资料库。此外,模拟考试环境,练习手撕代码,也是备考的重要部分。 最后,用户可能还想知道如何利用这些整理好的资料进行有效复习,比如制定学习计划,针对性练习高频题目,或者参加模拟考试。这些都是整理试题后的下一步行动,用户可能需要进一步的指导,但当前问题主要集中在整理方法上,所以回答应集中在如何系统化整理和归纳。</think>### 华为OD机考试题整理方法与归纳技巧 #### 一、试题整理方法 1. **多渠道收集** - **官方渠道**:关注华为招聘官网、官方开发者社区发布的样题或考试大纲[^1] - **技术论坛**:如牛客网、LeetCode讨论区,筛选用户分享的真题回忆录 - **社群资源**:加入备考群组(QQ/微信),整理群成员提供的题目片段 - **模拟平台**:使用第三方机考模拟平台(如CodeTop)获取结构化题目 2. **分类标注** - **题型分类**:算法题(动态规划、贪心算法)、数据结构题(链表、二叉树)、数学题(概率计算) - **难度分级**:按华为OD定义的★~★★★等级划分,例如: $$T(n) = O(n \log n) \quad \text{// 快速排序类题目通常为★★级}$$ - **版本标识**:通过时间戳(如2023Q3)或地域标识(如南京研究所版)区分 3. **真实性验证** - **交叉比对**:至少3个独立来源确认同一题目 - **代码验证**:对编程题编写测试用例,例如: ```python # 两数之和验证用例 assert two_sum([2,7,11,15], 9) == [0,1] ``` #### 二、归纳技巧 1. **结构化数据库** | 字段 | 说明 | 示例 | |------|------|------| | 题目ID | 唯一标识符 | HWOD2023-A01 | | 题干摘要 | 关键描述 | "二叉树层序遍历" | | 核心考点 | 知识点标签 | BFS/队列 | | 变体关联 | 相似题目链接 | HWOD2022-B05 | 2. **高频考点分析** - **Top 5算法**:快速排序、二分查找、DFS/BFS、滑动窗口、回溯法 - **数据结构热点**:链表翻转($O(1)$空间复杂度实现)、堆的应用、图的最短路径 - **数学相关**:排列组合计算(例如卡特兰数应用场景) 3. **版本差异处理** - **时间线对比**:制作版本演化矩阵 | 年度 | 新增题型 | 淘汰题型 | |------|----------|----------| | 2022 | 多线程同步问题 | 纯数学证明题 | | 2023 | 机器学习基础题 | 简单数组遍历 | - **地域差异**:某些研究所侧重操作系统题(如内存管理),其他偏向网络编程 #### 三、实践建议 1. **建立自动化流程** - 使用Python爬虫定期抓取论坛新帖(需遵守平台规则) - 用自然语言处理(NLP)提取题目关键特征 ```python # 示例:题干关键词提取 from sklearn.feature_extraction.text import TfidfVectorizer corpus = ["二叉树中序遍历实现","动态规划求最长子序列"] vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(corpus) ``` 2. **变体题目关联** - **同源题目组**:将本质相同但表述不同的题目聚类,例如: - "数组中的第K大元素"(快速选择算法) - "前K个高频元素"(堆+哈希表) 3. **考试环境模拟** - 限制IDE自动补全功能 - 严格遵循输入输出格式: ```text // 输入样例 3 1 2 3 // 输出要求 6 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值