华为笔试 华为秋招 华为笔试题 1112
笔试时间:2025年11月12日
往年笔试合集:
第一题:环形内存管理
有一个由若干个连续的内存单元组成的一个环形的内存块,我们现在需要从这个内存块中某个内存单元后申请指定大小的连续内存。
为了方便描述我们进行以下约定:
- 我们用一个10进制byte数字序列来描述这个内存块的现状:其中每一个数字为1个byte,表示内存块中8个连续的内存单元,它的每一个bit的值用于描述1个内存单元是否使用,bit为0时表示内存已使用,1表示空闲。
- 我们对环形内存块的每一个内存单元进行编号,假设数字序列共有n个数字,数字序列的第1个数的bit0到bit7,依次对应编号为015的内存单元,依次类推,第n个数字对应8n-8到8n-1的内存单元。从0到8n-1编号的内存单元保持物理上连续,编号越大,内存单元越靠后。编号0和8n-1的两个首尾内存单元相邻构成环形的内存。
现在需要在这个连续的内存块中的指定编号为m的内存单元之后(顺时针),找到长度为k的连续未使用的内存块,按以下规则优先进行匹配:
- 查找方向是从m+1和8n-1和0, m的区间依次查找满足条件的连续未使用的内存单元段
- 当有多个内存段满足条件时,优先在大小最接近申请大小连续内存段内,申请起始编号距离m最近的内存块
- 编号为j的内存单元到m内存单元的距离计算方式如下: j > m时,距离 = j - mj ≤ m时,距离 = j + 8n - m
输入描述
输入是一个字符串数字序列,至少包括2行:
- 第1行有两个数字: 第1个数字:申请的连续单元个数k,范围:0~65535第2个数字:m,在这个编号的内存单元后开始查找,范围:0~3600
- 从第2行开始为描述内存状态的数字序列(可能存在换行)。数字之间用空格或者换行隔开,最多500个数字,每个数字范围是0~255。
输出描述
输出为满足申请条件的内存段的起始内存单元编号。当没有满足条件的内存段时,输出-1。
样例输入
3 6
59 143
样例输出
15
参考题解
C++:
#include <iostream>
#include <vector>
#include <set>
#include <climits>
#include <algorithm>
using namespace std;
int main() {
string line;
getline(cin, line);
int k, m;
sscanf(line.c_str(), "%d %d", &k, &m);
vector<int> mem_bytes;
while (getline(cin, line)) {
if (line.empty()) break;
int val;
stringstream ss(line);
while (ss >> val) {
mem_bytes.push_back(val);
}
}
if (mem_bytes.empty()) {
cout << -1 << endl;
return 0;
}
int N = mem_bytes.size() * 8;
if (m >= N || k == 0) {
cout << -1 << endl;
return 0;
}
vector<int> mem_bits(N, 0);
for (int i = 0; i < mem_bytes.size(); i++) {
for (int j = 0; j < 8; j++) {
if ((mem_bytes[i] >> j) & 1) {
mem_bits[i * 8 + j] = 1;
}
}
}
vector<int> search_array(mem_bits);
search_array.insert(search_array.end(), mem_bits.begin(), mem_bits.end());
vector<pair<int, int>> maximal_blocks;
set<int> visited_starts;
int i = 0;
while (i < 2 * N) {
if (search_array[i] == 0) {
i++;
continue;
}
int start = i;
int length = 0;
int j = i;
while (j < 2 * N && search_array[j] == 1) {
length++;
j++;
}
int block_len = min(length, N);
int start_index = start % N;
if (visited_starts.find(start_index) == visited_starts.end()) {
maximal_blocks.push_back({start_index, block_len});
visited_starts.insert(start_index);
}
i = j;
}
vector<pair<int, int>> valid_blocks;
for (auto& block : maximal_blocks) {
if (block.second >= k) {
valid_blocks.push_back(block);
}
}
if (valid_blocks.empty()) {
cout << -1 << endl;
return 0;
}
int min_valid_size = INT_MAX;
for (auto& block : valid_blocks) {
min_valid_size = min(min_valid_size, block.second);
}
int best_start = -1;
int min_dist = INT_MAX;
for (auto& block : valid_blocks) {
if (block.second == min_valid_size) {
int dist;
if (block.first > m) {
dist = block.first - m;
} else {
dist = block.first + N - m;
}
if (dist < min_dist) {
min_dist = dist;
best_start = block.first;
}
}
}
cout << best_start << endl;
return 0;
}
Java:
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int m = sc.nextInt();
List<Integer> memBytes = new ArrayList<>();
while (sc.hasNext()) {
memBytes.add(sc.nextInt());
}
if (memBytes.isEmpty()) {
System.out.println(-1);
return;
}
int N = memBytes.size() * 8;
if (m >= N || k == 0) {
System.out.println(-1);
return;
}
int[] memBits = new int[N];
for (int i = 0; i < memBytes.size(); i++) {
for (int j = 0; j < 8; j++) {
if ((memBytes.get(i) >> j & 1) == 1) {
memBits[i * 8 + j] = 1;
}
}
}
int[] searchArray = new int[2 * N];
System.arraycopy(memBits, 0, searchArray, 0, N);
System.arraycopy(memBits, 0, searchArray, N, N);
List<int[]> maximalBlocks = new ArrayList<>();
Set<Integer> visitedStarts = new HashSet<>();
int i = 0;
while (i < 2 * N) {
if (searchArray[i] == 0) {
i++;
continue;
}
int start = i;
int length = 0;
int j = i;
while (j < 2 * N && searchArray[j] == 1) {
length++;
j++;
}
int blockLen = Math.min(length, N);
int startIndex = start % N;
if (!visitedStarts.contains(startIndex)) {
maximalBlocks.add(new int[]{startIndex, blockLen});
visitedStarts.add(startIndex);
}
i = j;
}
List<int[]> validBlocks = new ArrayList<>();
for (int[] block : maximalBlocks) {
if (block[1] >= k) {
validBlocks.add(block);
}
}
if (validBlocks.isEmpty()) {
System.out.println(-1);
return;
}
int minValidSize = Integer.MAX_VALUE;
for (int[] block : validBlocks) {
minValidSize = Math.min(minValidSize, block[1]);
}
int bestStart = -1;
int minDist = Integer.MAX_VALUE;
for (int[] block : validBlocks) {
if (block[1] == minValidSize) {
int dist;
if (block[0] > m) {
dist = block[0] - m;
} else {
dist = block[0] + N - m;
}
if (dist < minDist) {
minDist = dist;
bestStart = block[0];
}
}
}
System.out.println(bestStart);
}
}
Python:
import sys
def solve():
first_line = sys.stdin.readline().split()
if len(first_line) < 2:
print(-1)
return
k = int(first_line[0])
m = int(first_line[1])
mem_bytes = []
while True:
line = sys.stdin.readline()
if not line:
break
tokens = line.split()
if not tokens:
continue
mem_bytes.extend([int(s) for s in tokens])
if not mem_bytes:
print(-1)
return
N = len(mem_bytes) * 8
if m >= N:
print(-1)
return
if k == 0:
print(-1)
return
mem_bits = [0] * N
for i, byte_val in enumerate(mem_bytes):
for j in range(8):
if (byte_val >> j) & 1:
mem_bits[i * 8 + j] = 1
search_array = mem_bits + mem_bits
maximal_blocks = []
visited_starts = set()
i = 0
while i < 2 * N:
if search_array[i] == 0:
i += 1
continue
start = i
length = 0
j = i
while j < 2 * N and search_array[j] == 1:
length += 1
j += 1
block_len = min(length, N)
start_index = start % N
if start_index not in visited_starts:
maximal_blocks.append((start_index, block_len))
visited_starts.add(start_index)
i = j
valid_blocks = [block for block in maximal_blocks if block[1] >= k]
if not valid_blocks:
print(-1)
return
min_valid_size = min(block[1] for block in valid_blocks)
closest_size_blocks = [block for block in valid_blocks if block[1] == min_valid_size]
best_start = -1
min_dist = float('inf')
for start, length in closest_size_blocks:
dist = 0
if start > m:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025 春招笔试合集 文章被收录于专栏
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
