当前位置: 首页 > news >正文

华为OD机试真题——推荐多样性(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

在这里插入图片描述

2025 A卷 200分 题型

本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!

本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》

华为OD机试真题《推荐多样性》:


目录

    • 题目名称:推荐多样性
      • 题目描述
    • Java
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • python
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • JavaScript
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • C++
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • C语言
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • GO
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • 更多内容:


题目名称:推荐多样性


  • 知识点:队列操作、逻辑处理
  • 时间限制:1秒
  • 空间限制:256MB
  • 限定语言:不限

题目描述

推荐多样性需要从多个列表中选择元素,一次性返回N屏数据(窗口数量),每屏展示K个元素(窗口大小)。选择策略如下:

  1. 穿插处理:从第一个列表依次为每屏选一个元素,再从第二个列表选,依此类推。
  2. 均分分配:每个列表元素尽量均分N份,不足N份时全部分配完。例如:
    • 第一轮从列表1选4个元素分配到4个窗口;
    • 第二轮从列表2选4个元素分配;
    • 后续轮次继续循环,若元素不足则按剩余数量分配。

输入描述

  • 第一行为N(窗口数,1≤N≤10);
  • 第二行为K(每窗口元素数,1≤K≤100);
  • 后续行数不定(110行),每行为一个已排序的元素列表(元素数1100)。

输出描述

  • 合并后的元素列表,总数量为N*K。输出顺序为窗口1、窗口2……窗口N的元素依次拼接。

示例
输入:

4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出:

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19  

补充说明

  • 每个列表元素去重且足够满足窗口需求,无需处理不足情况。
  • 输出需保持同一列表元素顺序不变。

Java

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则是穿插处理均分分配:每个列表的元素尽量均分到N个窗口,处理顺序是依次循环处理每个列表的轮次,每次分配N个元素到各个窗口。

解题思路

  1. 均分分配:每个列表的元素被分成多个轮次,每个轮次取N个元素,依次分配到各个窗口。
  2. 穿插处理:处理顺序是依次循环处理每个列表的轮次,直到所有窗口填满。
  3. 动态处理:维护每个列表的当前轮次,每次处理一个轮次,分配元素到窗口,直到所有窗口满。

代码实现

import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int N = scanner.nextInt();int K = scanner.nextInt();scanner.nextLine(); // 消耗换行符List<List<Integer>> lists = new ArrayList<>();while (scanner.hasNextLine()) {String line = scanner.nextLine().trim();if (line.isEmpty()) break;List<Integer> list = new ArrayList<>();for (String numStr : line.split(" ")) {list.add(Integer.parseInt(numStr));}lists.add(list);}List<List<Integer>> windows = new ArrayList<>();for (int i = 0; i < N; i++) {windows.add(new ArrayList<>());}int[] currentRound = new int[lists.size()]; // 每个列表的当前轮次boolean allFull = false;while (!allFull) {allFull = true;for (int listIdx = 0; listIdx < lists.size(); listIdx++) {List<Integer> list = lists.get(listIdx);int round = currentRound[listIdx];int start = (round - 1) * N;if (start >= list.size()) continue;int end = Math.min(start + N, list.size());List<Integer> elements = list.subList(start, end);for (int windowIdx = 0; windowIdx < elements.size(); windowIdx++) {if (windowIdx >= N) break;List<Integer> window = windows.get(windowIdx);if (window.size() < K) {window.add(elements.get(windowIdx));}}currentRound[listIdx]++; // 更新轮次// 检查所有窗口是否已满boolean currentAllFull = true;for (List<Integer> window : windows) {if (window.size() < K) {currentAllFull = false;break;}}if (currentAllFull) {allFull = true;break;} else {allFull = false;}}}// 拼接结果List<Integer> result = new ArrayList<>();for (List<Integer> window : windows) {result.addAll(window);}// 输出for (int i = 0; i < result.size(); i++) {if (i > 0) System.out.print(" ");System.out.print(result.get(i));}}
}

代码详细解析

  1. 输入处理

    • 读取窗口数N和每窗口元素数K
    • 读取所有列表,存入lists
  2. 初始化窗口

    • 创建N个窗口,每个窗口用列表存储元素。
  3. 轮次处理

    • 维护currentRound数组,记录每个列表的当前处理轮次。
    • 循环处理每个列表的轮次,每次取N个元素分配到窗口。
  4. 动态分配

    • 每个轮次从当前列表取N个元素,分配到对应窗口。
    • 如果窗口未满,添加元素;否则跳过。
  5. 检查填满状态

    • 每次处理完一个列表的轮次后,检查所有窗口是否已满,若满则提前结束。
  6. 输出结果

    • 将所有窗口的元素按顺序拼接,输出。

示例测试

示例1输入:
4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19
示例2输入:
2  
3  
1 2 3 4  
5 6  

输出

1 5 2 3 6 4
示例3输入:
3  
2  
10 20 30  
40 50  
60  

输出

10 40 60 20 50 30

综合分析

  1. 时间复杂度:O(M*K),M为列表数,每个元素处理一次。
  2. 空间复杂度:O(N*K),存储窗口元素。
  3. 优势
    • 严格满足题目要求:按轮次处理,确保穿插分配。
    • 高效性:动态处理,提前终止填满的窗口。
  4. 适用场景:处理多列表元素分配,要求严格按规则分配到多个窗口。

python

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则为:

  1. 穿插处理:从第一个列表开始依次为每个窗口分配元素,再处理下一个列表。
  2. 均分分配:每个列表元素尽量均分到N个窗口,不足时全部分配。

解题思路

  1. 输入处理:读取窗口数N、每窗口元素数K,以及多个元素列表。
  2. 轮次分配:每个列表按轮次分配元素,每次为每个窗口分配一个元素。
  3. 动态填充:维护每个列表的当前轮次,直到所有窗口填满。

代码实现

import sysdef main():# 读取输入参数lines = [line.strip() for line in sys.stdin if line.strip()]N = int(lines[0])K = int(lines[1])lists = [[int(num) for num in line.split()] for line in lines[2:]]# 初始化N个空窗口windows = [[] for _ in range(N)]# 记录每个列表的当前轮次(从0开始计数)current_round = [0] * len(lists)# 轮次分配直到所有窗口填满while True:all_full = all(len(window) >= K for window in windows)if all_full:break# 遍历每个列表进行一轮分配for list_idx in range(len(lists)):current_list = lists[list_idx]round_num = current_round[list_idx]# 计算当前轮次需要分配的起始索引和结束索引start = round_num * Nend = start + N# 取出当前轮次的元素(可能不足N个)elements = current_list[start:end]# 将元素按顺序分配到窗口for i, elem in enumerate(elements):window_idx = i % N  # 确保不超过窗口数量if len(windows[window_idx]) < K:windows[window_idx].append(elem)# 更新当前列表的轮次(如果还有剩余元素)if end < len(current_list):current_round[list_idx] += 1else:current_round[list_idx] = -1  # 标记列表已分配完毕# 拼接结果result = []for window in windows:result.extend(window[:K])  # 确保每个窗口不超过K个元素print(' '.join(map(str, result)))if __name__ == "__main__":main()

代码详细解析

  1. 输入处理

    • 读取所有非空行到列表 lines
    • N = int(lines[0]):读取窗口数量
    • K = int(lines[1]):读取每窗口元素数
    • lists = [...]:将剩余行转为整数列表的列表
  2. 初始化数据结构

    • windows = [[] for _ in range(N)]:创建N个空窗口
    • current_round = [0] * len(lists):记录每个列表的当前轮次
  3. 轮次分配逻辑

    while True:all_full = all(len(window) >= K for window in windows)if all_full:break
    
    • 检查所有窗口是否已填满,若满则终止循环
  4. 处理每个列表的当前轮次

    start = round_num * N
    end = start + N
    elements = current_list[start:end]
    
    • 计算当前轮次需要分配的元素范围
  5. 元素分配

    for i, elem in enumerate(elements):window_idx = i % Nif len(windows[window_idx]) < K:windows[window_idx].append(elem)
    
    • 将元素按顺序分配到窗口(循环分配到各窗口)
  6. 更新轮次状态

    if end < len(current_list):current_round[list_idx] += 1
    else:current_round[list_idx] = -1
    
    • 如果当前列表还有剩余元素,增加轮次;否则标记为已完成
  7. 结果拼接

    result = []
    for window in windows:result.extend(window[:K])
    
    • 按顺序拼接所有窗口的前K个元素

示例测试

示例1输入:
4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19
示例2输入:
2  
3  
1 2 3 4  
5 6  

输出

1 5 2 3 6 4
示例3输入:
3  
2  
10 20 30  
40 50  
60  

输出

10 40 60 20 50 30

综合分析

  1. 时间复杂度:O(MNK),M为列表数量,每个元素处理一次。
  2. 空间复杂度:O(N*K),存储所有窗口元素。
  3. 优势
    • 严格顺序分配:保持列表元素原始顺序。
    • 动态终止:检测到所有窗口填满后立即终止循环。
  4. 适用场景:需要将多个列表元素按轮次均分到多个窗口的场景。

JavaScript

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则为:

  1. 穿插处理:依次处理每个列表的轮次,为每个窗口分配一个元素。
  2. 均分分配:每个列表的元素尽量均分到N个窗口,不足时全部分配。

解题思路

  1. 输入处理:读取窗口数N、每窗口元素数K,以及多个元素列表。
  2. 轮次分配:每个列表按轮次分配元素,每次为每个窗口分配一个元素。
  3. 动态填充:维护每个列表的当前轮次,直到所有窗口填满。

代码实现

const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout,terminal: false
});let lines = [];
rl.on('line', (line) => {lines.push(line.trim());
});rl.on('close', () => {const N = parseInt(lines[0]);const K = parseInt(lines[1]);const lists = lines.slice(2).map(line => line.split(' ').map(Number));// 初始化N个窗口,每个窗口初始为空数组const windows = Array.from({ length: N }, () => []);// 记录每个列表的当前轮次(初始为0)const rounds = new Array(lists.length).fill(0);let listIndex = 0; // 当前处理的列表索引let allFull = false;while (!allFull) {const currentList = lists[listIndex];const currentRound = rounds[listIndex];// 如果当前列表的轮次已处理完所有元素,跳过if (currentRound === -1) {listIndex = (listIndex + 1) % lists.length;continue;}const start = currentRound * N;const end = start + N;const elements = currentList.slice(start, end);// 将元素按顺序分配到窗口for (let i = 0; i < elements.length; i++) {const windowIndex = i % N;if (windows[windowIndex].length < K) {windows[windowIndex].push(elements[i]);}}// 检查所有窗口是否已填满allFull = windows.every(window => window.length === K);if (allFull) break;// 更新当前列表的轮次if (end < currentList.length) {rounds[listIndex] += 1;} else {rounds[listIndex] = -1; // 标记该列表已处理完所有轮次}// 移动到下一个列表listIndex = (listIndex + 1) % lists.length;}// 拼接结果并输出const result = windows.flat().join(' ');console.log(result);
});

代码详细解析

  1. 输入处理

    • 使用 readline 逐行读取输入,存入 lines 数组。
    • N 为窗口数量,K 为每窗口元素数。
    • lists 存储所有代表团元素列表。
  2. 初始化数据结构

    • windows 数组表示N个窗口,每个初始为空数组。
    • rounds 数组记录每个列表的当前轮次,初始为0。
  3. 轮次处理逻辑

    • 依次处理每个列表的当前轮次,取出该轮次的元素。
    • 将元素按顺序分配到窗口0到N-1。
    • 更新当前列表的轮次,若元素已分配完毕则标记为-1。
  4. 填满检查

    • 每次分配后检查所有窗口是否已填满,若满则退出循环。
  5. 结果拼接

    • 将各窗口元素按顺序拼接成字符串输出。

示例测试

示例1输入:
4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19  
示例2输入:
2  
3  
1 2 3 4  
5 6  

输出

1 5 2 3 6 4  
示例3输入:
3  
2  
10 20 30  
40 50  
60  

输出

10 40 60 20 50 30  

综合分析

  1. 时间复杂度O(MNK)

    • M 为列表数量,N 为窗口数,K 为每窗口元素数。每个元素处理一次。
  2. 空间复杂度O(N*K)

    • 存储窗口元素,总空间与窗口数量和元素数成正比。
  3. 优势

    • 严格顺序分配:确保元素按轮次交叉分配到窗口。
    • 高效合并:动态更新轮次,避免重复处理。
  4. 适用场景

    • 需要将多个列表元素按规则分配到多个窗口的场景。

C++

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则是穿插处理均分分配:每个列表的元素尽量均分到N个窗口,处理顺序是依次循环处理每个列表的轮次。

解题思路

  1. 轮次分配:每个列表的元素按轮次分配到窗口,每个轮次取N个元素。
  2. 循环窗口:每个轮次的元素依次分配到窗口的循环位置(i % N),确保所有窗口均匀填充。
  3. 动态处理:维护每个列表的当前轮次,直到所有窗口填满。

代码实现

#include <iostream>
#include <vector>
#include <sstream>
#include <string>using namespace std;int main() {int N, K;cin >> N >> K;cin.ignore();  // 忽略首行换行符vector<vector<int>> lists;string line;// 读取所有列表while (getline(cin, line)) {if (line.empty()) continue;vector<int> list;istringstream iss(line);int num;while (iss >> num) {list.push_back(num);}lists.push_back(list);}vector<vector<int>> windows(N);  // 初始化N个窗口vector<int> rounds(lists.size(), 0);  // 每个列表的当前轮次bool all_full = false;while (!all_full) {bool any_processed = false;// 依次处理每个列表的当前轮次for (int list_idx = 0; list_idx < lists.size(); ++list_idx) {vector<int>& current_list = lists[list_idx];int& round = rounds[list_idx];int start = round * N;if (start >= current_list.size()) continue;int end = min(start + N, static_cast<int>(current_list.size()));vector<int> elements(current_list.begin() + start, current_list.begin() + end);// 将元素循环分配到窗口for (int i = 0; i < elements.size(); ++i) {int window_idx = i % N;  // 计算窗口索引if (windows[window_idx].size() < K) {windows[window_idx].push_back(elements[i]);}}any_processed = true;round++;  // 更新轮次// 检查所有窗口是否已满all_full = true;for (auto& w : windows) {if (w.size() < K) {all_full = false;break;}}if (all_full) break;}if (!any_processed) break;  // 所有列表处理完毕}// 输出结果vector<int> result;for (auto& w : windows) {result.insert(result.end(), w.begin(), w.end());}for (size_t i = 0; i < result.size(); ++i) {if (i > 0) cout << " ";cout << result[i];}cout << endl;return 0;
}

代码详细解析

  1. 输入处理

    • 读取窗口数N和每窗口元素数K
    • 逐行读取每个列表,分割字符串为整数数组。
  2. 初始化数据结构

    • windows存储每个窗口的元素。
    • rounds记录每个列表的当前轮次。
  3. 轮次处理

    • 遍历每个列表的当前轮次,取出元素块。
    • 将元素循环分配到窗口(i % N),确保均匀填充。
  4. 动态更新

    • 更新当前轮次,检查窗口是否填满。
    • 若所有窗口填满,提前终止循环。
  5. 结果输出

    • 按窗口顺序拼接结果并输出。

示例测试

示例1输入:
4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19  
示例2输入:
2  
3  
1 2 3 4  
5 6  

输出

1 5 2 3 6 4  
示例3输入:
3  
2  
10 20 30  
40 50  
60  

输出

10 40 60 20 50 30  

综合分析

  1. 时间复杂度:O(MNK),M为列表数量,每个元素处理一次。
  2. 空间复杂度:O(N*K),存储窗口元素。
  3. 优势
    • 严格轮次分配:元素循环分配到窗口,确保均匀填充。
    • 高效内存使用:仅维护必要数据结构。
    • 输入鲁棒性:自动处理不同输入格式。
  4. 适用场景:需要将多个列表元素均分到多个窗口的场景。

C语言

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则是穿插处理均分分配:每个列表的元素尽量均分到N个窗口,处理顺序是依次循环处理每个列表的轮次。

解题思路

  1. 输入处理:读取窗口数N和每窗口元素数K,以及多个元素列表。
  2. 轮次分配:每个列表按轮次取出最多N个元素,依次分配到各个窗口。
  3. 动态填充:维护每个列表的当前轮次,循环处理直到所有窗口填满。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LISTS 100     // 最大列表数
#define MAX_ELEMENTS 1100 // 每个列表最大元素数typedef struct {int *elements; // 元素数组int size;       // 元素数量
} List;int main() {int N, K;scanf("%d %d", &N, &K);while (getchar() != '\n'); // 清空输入缓冲区List lists[MAX_LISTS]; // 存储所有列表int num_lists = 0;     // 实际列表数// 读取所有列表char line[10000];while (fgets(line, sizeof(line), stdin)) {if (line[0] == '\n') continue; // 跳过空行line[strcspn(line, "\n")] = '\0'; // 去除换行符int *elements = malloc(MAX_ELEMENTS * sizeof(int));int count = 0;char *token = strtok(line, " ");while (token != NULL) {elements[count++] = atoi(token);token = strtok(NULL, " ");}lists[num_lists].elements = elements;lists[num_lists].size = count;num_lists++;}// 初始化窗口:每个窗口最多存储K个元素int **windows = (int **)malloc(N * sizeof(int *));for (int i = 0; i < N; i++) {windows[i] = (int *)malloc(K * sizeof(int));memset(windows[i], 0, K * sizeof(int));}int *window_counts = (int *)calloc(N, sizeof(int)); // 各窗口当前元素数int *rounds = (int *)calloc(num_lists, sizeof(int)); // 每个列表的当前轮次int current_list = 0; // 当前处理的列表索引// 主循环:依次处理各列表的轮次while (1) {// 检查所有窗口是否已满int all_full = 1;for (int i = 0; i < N; i++) {if (window_counts[i] < K) {all_full = 0;break;}}if (all_full) break;List *list = &lists[current_list];int round = rounds[current_list];int start = round * N; // 当前轮次的起始索引if (start >= list->size) { // 当前轮次无元素current_list = (current_list + 1) % num_lists;continue;}int end = start + N;if (end > list->size) end = list->size;int num_elements = end - start;// 分配元素到窗口for (int i = 0; i < num_elements; i++) {int window_idx = i; // 当前元素分配到第i个窗口if (window_idx >= N) break; // 超出窗口数if (window_counts[window_idx] < K) {windows[window_idx][window_counts[window_idx]] = list->elements[start + i];window_counts[window_idx]++;}}rounds[current_list]++; // 更新轮次current_list = (current_list + 1) % num_lists; // 处理下一个列表}// 输出结果:按窗口顺序拼接for (int w = 0; w < N; w++) {for (int i = 0; i < K; i++) {printf("%d ", windows[w][i]);}}printf("\n");// 释放内存for (int i = 0; i < num_lists; i++) free(lists[i].elements);for (int i = 0; i < N; i++) free(windows[i]);free(windows);free(window_counts);free(rounds);return 0;
}

代码详细解析

  1. 输入处理

    • 使用 scanf 读取窗口数 N 和每窗口元素数 K
    • 清空输入缓冲区以避免后续读取错误。
    • 使用 fgets 逐行读取每个列表,分割为整数数组。
  2. 初始化数据结构

    • List 结构数组存储所有输入列表的元素和长度。
    • windows 二维数组存储每个窗口的元素,window_counts 数组记录每个窗口的当前元素数。
    • rounds 数组记录每个列表的当前轮次。
  3. 主循环处理

    • 检查所有窗口是否已填满,若填满则终止循环。
    • 处理当前列表的当前轮次,计算起始索引 start
    • 取出当前轮次的元素,按顺序分配到窗口0到N-1。
    • 更新当前列表的轮次,并移动到下一个列表。
  4. 结果输出

    • 按窗口顺序输出每个窗口的K个元素。
  5. 内存释放

    • 释放动态分配的列表、窗口和计数器数组的内存。

示例测试

示例1输入:
4
7
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19 
示例2输入:
2
3
1 2 3 4
5 6

输出

1 5 2 3 6 4 
示例3输入:
3
2
10 20 30
40 50
60

输出

10 40 60 20 50 30 

综合分析

  1. 时间复杂度:O(MNK),M为列表数量,每个元素处理一次。
  2. 空间复杂度:O(N*K),存储所有窗口元素。
  3. 优势
    • 严格轮次分配:确保元素按轮次分配到各窗口。
    • 高效内存管理:动态分配内存,避免浪费。
    • 输入鲁棒性:处理各种输入格式,包括空行和多余空格。
  4. 适用场景:需要将多个列表元素按规则均分到多个窗口的场景。

GO

问题分析

我们需要将多个列表中的元素按特定规则分配到N个窗口,每个窗口包含K个元素。规则是穿插处理均分分配:每个列表的元素尽量均分到N个窗口,处理顺序是依次循环处理每个列表的轮次。


解题思路

  1. 输入处理:读取窗口数N、每窗口元素数K,以及多个元素列表。
  2. 轮次分配:每个列表按轮次分配元素,每次分配最多N个元素到各个窗口。
  3. 动态填充:维护每个列表的当前轮次,循环处理直到所有窗口填满。

代码实现

package mainimport ("bufio""fmt""os""strconv""strings"
)func main() {scanner := bufio.NewScanner(os.Stdin)// 读取输入参数scanner.Scan()N, _ := strconv.Atoi(scanner.Text()) // 窗口数scanner.Scan()K, _ := strconv.Atoi(scanner.Text()) // 每窗口元素数var lists [][]int// 读取所有列表for scanner.Scan() {line := scanner.Text()if line == "" {break}parts := strings.Split(line, " ")var list []intfor _, p := range parts {num, _ := strconv.Atoi(p)list = append(list, num)}lists = append(lists, list)}// 初始化N个窗口,每个窗口最多存储K个元素windows := make([][]int, N)for i := range windows {windows[i] = make([]int, 0, K)}// 记录每个列表的当前轮次(从0开始)rounds := make([]int, len(lists))currentList := 0 // 当前处理的列表索引for {// 检查所有窗口是否已满allFull := truefor _, w := range windows {if len(w) < K {allFull = falsebreak}}if allFull {break}// 处理当前列表的当前轮次list := lists[currentList]round := rounds[currentList]start := round * Nif start >= len(list) { // 当前列表已处理完所有轮次currentList = (currentList + 1) % len(lists)continue}end := start + Nif end > len(list) {end = len(list)}elements := list[start:end]// 将元素循环分配到窗口for i, elem := range elements {windowIdx := i % Nif len(windows[windowIdx]) < K {windows[windowIdx] = append(windows[windowIdx], elem)}}// 更新轮次并切换到下一个列表rounds[currentList]++currentList = (currentList + 1) % len(lists)}// 拼接结果并输出result := make([]int, 0, N*K)for _, w := range windows {result = append(result, w...)}for i, num := range result {if i > 0 {fmt.Print(" ")}fmt.Print(num)}fmt.Println()
}

代码详细解析

  1. 输入处理

    • 使用 bufio.Scanner 读取输入,前两行获取 NK
    • 后续行读取每个列表,分割为整数数组存入 lists
  2. 初始化窗口

    windows := make([][]int, N) // 创建N个窗口切片
    for i := range windows {windows[i] = make([]int, 0, K) // 每个窗口初始化为容量K的空切片
    }
    
  3. 轮次处理逻辑

    • rounds 数组记录每个列表的当前轮次。
    • 循环检查窗口是否填满,若填满则退出循环。
    • 处理当前列表的轮次,计算起始和结束索引:
      start := round * N
      end := start + N
      
    • 将元素循环分配到窗口(i % N 确定窗口索引)。
  4. 结果拼接

    • 遍历所有窗口,按顺序拼接元素到 result 切片。
    • 遍历输出结果,用空格分隔元素。

示例测试

示例1输入:
4  
7  
0 1 2 3 4 5 6 7 8 9  
10 11 12 13 14 15 16 17 18 19  
20 21 22 23 24 25 26 27 28 29  

输出

0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19  
示例2输入:
2  
3  
1 2 3 4  
5 6  

输出

1 5 2 3 6 4  
示例3输入:
3  
2  
10 20 30  
40 50  
60  

输出

10 40 60 20 50 30  

综合分析

  1. 时间复杂度:O(MNK)

    • M为列表数量,每个元素处理一次,最多分配N*K次。
  2. 空间复杂度:O(N*K)

    • 存储所有窗口元素,总空间为N*K。
  3. 优势

    • 严格轮次分配:确保元素按规则均匀分配到窗口。
    • 高效内存管理:Go的切片动态扩展,避免内存浪费。
    • 输入鲁棒性:自动处理不同长度的输入行。
  4. 适用场景

    • 需要将多个列表元素按规则均分到多个窗口的场景,尤其适合动态数据分配需求。

更多内容:

https://www.kdocs.cn/l/cvk0eoGYucWA

本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!

相关文章:

  • ubuntu(28):ubuntu系统多版本conda和多版本cuda共存
  • ElementUi的Dropdown下拉菜单的详细介绍及使用
  • JAVA常用分布式锁Redisson
  • Redis相关
  • FX10(CYUSB4014)USB3.2(10Gbps)开发笔记分享(1):硬件设计与开发环境搭建
  • Go 语言 Map(集合)
  • 真.从“零”搞 VSCode+STM32CubeMx+C <2>调试+烧录
  • 力扣-234.回文链表
  • 黑马Redis(三)黑马点评项目
  • 【HTTP/3:互联网通信的量子飞跃】
  • 【QQmusic自定义控件实现音乐播放器核心交互逻辑】第三章
  • OpenHarmony - 小型系统内核(LiteOS-A)(十),魔法键使用方法,用户态异常信息说明
  • git版本回退 | 远程仓库的回退 (附实战Demo)
  • 从零开始掌握Linux数据流:管道与重定向完全指南
  • 支持Function Call的本地ollama模型对比评测-》开发代理agent
  • 工业排风轴流风机:强劲动力与节能设计的完美融合
  • websheet 之 VUE使用
  • 基于 Netmiko 的网络设备自动化操作
  • 【器件专题1——IGBT第2讲】IGBT 基本工作原理:从结构到特性,一文解析 “电力电子心脏” 的核心机制
  • 人工智能与机器学习:Python从零实现性回归模型
  • 四川甘孜州白玉县发生4.9级地震,震源深度10千米
  • 来论|这无非就是一只“纸老虎”:评特朗普政府“关税战”
  • 调查丨当节气出现“时差”,陕西的果农们经历着什么?
  • 政治局会议:要提高中低收入群体收入,设立服务消费与养老再贷款
  • 中央空管办组织加强无人机“黑飞”“扰航”查处力度
  • 目前中美未进行任何经贸谈判,外交部、商务部再次表明中方立场