小米笔试 小米笔试题 0809
笔试时间:2025年8月9日
往年笔试合集:
第一题:答题闯关
某答题闯关节目设置了m道题目(编号1到m),规则要求将这些题目分为两轮闯关赛,每轮至少包含1道题,所有题目必须分配到两轮中。 共有n名选手参加比赛,每位选手能答对的题目范围是连续的一段(用L~R描述,表示该选手能答对第L到第R号题)。 选手只要能答对某一轮的所有题目(即该轮题目范围完全被选手的答题范围覆盖),就能晋级到复赛阶段。为了节目效果,导演想让尽可能多的选手晋级复赛。请在所有可能的题目分配方式中,计算最多有多少名选手可以晋级。
输入描述
第一行包含两个正整数n和m(1≤n≤50000,1≤m≤100000);
接下来n行,每行有两个正整数L_i和R_i,表示第i名选手能答对的题目范围(1≤L_i≤R_i≤m)。
输出描述
输出一个整数,表示最多可以晋级的选手数量。
样例输入
4 8
4 7
1 4
5 8
2 5
样例输出
3
样例解释 有4个参赛选手,8道试题: 第一位选手可作答4~7题; 第二位选手可作答1~4题; 第三位选手可作答5~8题; 第四位选手可作答2~5题。 此时有多种情况,其中一种情况为:将两轮闯关的题目分为4和除4外的其他题,此时选手1,2,4可在第一轮得到满分,进入复赛。
参考题解
是用差分数组统计每个题目被多少玩家覆盖。具体做法是:对每位玩家的答题区间 [L,R],在差分数组 diffArray 中对 diffArray[L] 加 1,对 diffArray[R+1] 减 1,最后通过前缀和计算每道题的覆盖人数,并取最大值作为答案。这样避免了逐题遍历每位玩家的区间
C++:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int playerCount, questionCount;
cin >> playerCount >> questionCount;
// 差分数组,大小为问题数量+3以避免越界
vector<int> diffArray(questionCount + 3, 0);
for (int i = 0; i < playerCount; ++i) {
int L, R;
cin >> L >> R;
diffArray[L] += 1;
diffArray[R + 1] -= 1;
}
int currentCover = 0;
int maxAdvancing = 0;
// 计算每个问题的覆盖人数并找到最大值
for (int q = 1; q <= questionCount; ++q) {
currentCover += diffArray[q];
if (currentCover > maxAdvancing) {
maxAdvancing = currentCover;
}
}
cout << maxAdvancing << endl;
return 0;
}
Java:
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
int playerCount = scanner.nextInt();
int questionCount = scanner.nextInt();
int[] diffArray = new int[questionCount + 3];
for (int i = 0; i < playerCount; ++i) {
int L = scanner.nextInt();
int R = scanner.nextInt();
diffArray[L] += 1;
diffArray[R + 1] -= 1;
}
int currentCover = 0;
int maxAdvancing = 0;
for (int q = 1; q <= questionCount; ++q) {
currentCover += diffArray[q];
if (currentCover > maxAdvancing) maxAdvancing = currentCover;
}
System.out.println(maxAdvancing);
scanner.close();
}
}
Python:
def main():
import sys
input = sys.stdin.read().split()
ptr = 0
player_count = int(input[ptr])
ptr += 1
question_count = int(input[ptr])
ptr += 1
# 初始化差分数组,大小为问题数量+3以避免越界
diff_array = [0] * (question_count + 3)
for _ in range(player_count):
L = int(input[ptr])
ptr += 1
R = int(input[ptr])
ptr += 1
diff_array[L] += 1
diff_array[R + 1] -= 1
current_cover = 0
max_advancing = 0
# 计算每个问题的覆盖人数并找到最大值
for q in range(1, question_count + 1):
current_cover += diff_array[q]
if current_cover > max_advancing:
max_advancing = current_cover
print(max_advancing)
if __name__ == "__main__":
main()
第二题
小钟在一张长为n、宽为m的网格图上摆放积木。图上有一些格子是特殊格子,小钟有无限个尺寸为1×3或3×1的积木。每次摆放积木需满足以下条件: 积木至少有一端与特殊格子重合; 只能在网格图内摆放,不能超出; 当前要摆放的积木不能与已摆放的积木重叠。 小钟会一直按上述要求摆放积木,直到无法再摆放为止。小爱想知道网格图最终有多少种可能的局面,两种局面不同,当且仅当网格图中存在某个格子,一种局面中该格子被积木覆盖,另一种局面中没有被覆盖。 1≤n, m≤8,特殊格子数量不超过13,数据随机生成。
输入描述
第一行有两个整数n(1≤n≤8)、m(1≤m≤8),分别表示网格图的长和宽。 接下来n行,每行输入m个字符: 若网格图第i行第j列位置是特殊格子,则字符为*; 否则为.。
输出描述
输出一个整数,表示网格图最终可能的局面个数。
样例输入
4 4
....
...*
.*..
....
样例输出
2
说明: 样例输入 2 3 3 样例输出 2 1 样例解释 对于第一个样例,两种可能的游戏结束局面如下: ... ..* .....*.... .*** .*** ....对于第二个样例,可以横着摆三行每行一个积木,也可以纵着摆三列每列一个积木,但是这两种方式所导致的最终的局面是相同的,因此可能的局面数是 1。
参考题解
把所有可能的积木摆放位置用位掩码表示,再通过最大团枚举寻找所有可能的覆盖组合,并记录每个组合能覆盖的格子集合。最终答案是这些覆盖集合的不同个数。位运算保证了摆放冲突检测的高效性,避免了重复搜索,从而在可行的时间内枚举所有组合情况。
C++:
#include <iostream>
#include <vector>
#include <unordered_set>
#include <cstdint>
using namespace std;
static int rows, cols;
static vector<uint64_t> placementMasks;
static vector<uint64_t> compatibilityMask;
static unordered_set<uint64_t> finalCoverMasks;
static int cellIndex(int r, int c) { return r * cols + c; }
static void enumerateMaximalSets(uint64_t candidateSet, uint64_t excludedSet, uint64_t currentCover) {
if (candidateSet == 0ULL && excludedSet == 0ULL) {
finalCoverMasks.insert(currentCover);
return;
}
uint64_t unionSet = candidateSet | excludedSet;
int pivotIndex = __builtin_ctzll(unionSet);
int bestCount = -1;
uint64_t tmp = unionSet;
while (tmp != 0ULL) {
int u = __builtin_ctzll(tmp);
int cnt = __builtin_popcountll(candidateSet & compatibilityMask[u]);
if (cnt > bestCount) {
bestCount = cnt;
pivotIndex = u;
}
tmp &= tmp - 1ULL;
}
uint64_t candidates = candidateSet & ~compatibilityMask[pivotIndex];
while (candidates != 0ULL) {
int v = __builtin_ctzll(candidates);
uint64_t bitV = 1ULL << v;
uint64_t newCandidate = candidateSet & compatibilityMask[v];
uint64_t newExcluded = excludedSet & compatibilityMask[v];
uint64_t newCover = currentCover | placementMasks[v];
enumerateMaximalSets(newCandidate, newExcluded, newCover);
candidateSet &= ~bitV;
excludedSet |= bitV;
candidates &= candidates - 1ULL;
}
}
int main() {
cin >> rows >> cols;
vector<string> grid(rows);
for (int r = 0; r < rows; ++r) {
cin >> grid[r];
}
vector<pair<int, int>> specialCells;
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
if (grid[r][c] == '*') {
specialCells.emplace_back(r, c);
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
