淘天笔试 淘天笔试题 0322
笔试时间:2025年03月22日
历史笔试传送门:
第一题
题目:点名
小兴的班上有n个人,他们总共要上m节课。每节课会有一次点名活动,第i节课会随机选取 ki个不同的学生进行点名,如果这个学生没有到达,则会被记录一次“旷课”。每个人起始的平时成绩为100,每次“旷课”会导致平时分下降10点(下降到负数则视为0)。学生的最终成绩为平时成绩的40%加上期末考试成绩的60%。现在小兴给你他们班上n个人每节课的上课情况以及期末考试成绩ai,请你按照最终成绩从大到小输出每个学生的编号以及他们的最终成绩(保留2位小数),如果最终成绩相同,则编号小的优先输出。
输入描述
第一行两个整数n,m;
第二行n个整数ai;
接下来n行每行m个整数表示 bij∈ {0,1},如果bij=0则表示第i个人没有参加第j节课,否则这节课参加了;
接下来m行,第i行先输入一个整数ki代表第i节课点名的人数,随后在同一行输入ki个互不相同的整数,表示点到的学生编号;
输出描述
输出n行,按顺序输出每个人的编号、最终成绩(保留两位小数)。
样例输入一
3 2
100 100 100
1 0
0 1
1 1
3 1 2 3
1 1
样例输出一
3 100.00
1 96.00
2 96.00
说明:
第一节课对所有人进行了点名,其中第二位同学没有到场,平时分变为90分。
第二节课对第一名学生进行了点名,没有到场,平时分变为90分。
最终三个人成绩分别为[96,96,100]。
样例输入二
7 3
64 33 32 98 49 18 88
0 1 0
0 0 0
0 0 1
0 1 0
0 0 0
1 0 1
0 0 1
2 1 2
0
2 1 2
样例输出二
4 98.80
7 92.80
1 70.40
5 69.40
3 59.20
2 51.80
6 50.80
参考题解
模拟。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h>
using namespace std;
int b[1010][110];
int p[1010];
bool cmp(pair<int,int> a,pair<int,int> b){
if(a.second != b.second) return b.second < a.second;
return a.first < b.first;
}
int main() {
int n,m;
cin >> n >> m;
vector<int> a(n);
for(int i = 0;i < n;i++) cin >> a[i];
for(int i = 0;i < n;i++){
p[i] = 100;
for(int j = 0;j < m;j++) cin >> b[i][j];
}
for(int i = 0;i < m;i++){
int k;
cin >> k;
for(int j = 0;j < k;j++) {
int x;
cin >> x;
if(b[x - 1][i] == 0) p[x - 1] = max(0,p[x - 1] - 10);
}
}
vector<pair<int,int>> info;
for(int i = 0;i < n;i++){
info.push_back(make_pair(i,4*p[i] + 6*a[i]));
}
sort(info.begin(),info.end(),cmp);
for(int i = 0;i < n;i++){
cout << info[i].first + 1 << " ";
cout << fixed << setprecision(2) << (double)info[i].second / 10 << endl;
}
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 学生数量
int m = scanner.nextInt(); // 课程数量
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt(); // 额外得分因子
}
int[][] b = new int[n][m]; // 学生在每门课的及格标志
int[] p = new int[n]; // 初始分数 100
Arrays.fill(p, 100);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
b[i][j] = scanner.nextInt();
}
}
for (int i = 0; i < m; i++) {
int k = scanner.nextInt();
for (int j = 0; j < k; j++) {
int x = scanner.nextInt();
if (b[x - 1][i] == 0) {
p[x - 1] = Math.max(0, p[x - 1] - 10);
}
}
}
List<int[]> info = new ArrayList<>();
for (int i = 0; i < n; i++) {
int score = 4 * p[i] + 6 * a[i];
info.add(new int[]{i, score});
}
info.sort((o1, o2) -> {
if (o1[1] != o2[1]) return Integer.compare(o2[1], o1[1]); // 分数降序
return Integer.compare(o1[0], o2[0]); // 编号升序
});
for (int[] entry : info) {
System.out.printf("%d %.2f\n", entry[0] + 1, entry[1] / 10.0);
}
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = [[0]*m for _ in range(n)]
p = [100]*n
for i in range(n):
b[i] = list(map(int, input().split()))
for i in range(m):
k = int(input())
x_list = list(map(int, input().split()))
for x in x_list:
if b[x-1][i] == 0:
p[x-1] = max(0, p[x-1] - 10)
info = []
for i in range(n):
score = 4 * p[i] + 6 * a[i]
info.append((i, score))
# 按分数降序,编号升序排序
info.sort(key=lambda x: (-x[1], x[0]))
for idx, score in info:
print(f"{idx+1} {score/10:.2f}")
第二题
题目:简单挖矿
有n名矿工,编号依次为1到n,他们按照编号由小到大的顺序,依次进入同一个矿道挖矿(即等到前一个人挖完矿下一个人才会去挖矿)。
矿道里有m处矿,第j处矿的高度为bj(即j处高度[1, bj]的位置都有1单位的矿物,
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南


