阿里云笔试 阿里云笔试题 研发岗 0511
笔试时间:2025年5月11日
往年笔试合集:
第一题
小歪正在学习字符串和声,字符串仅由小写字母和连接线‘-’构成。我们使用竖线‘|’来划分小结,例如,|do-do-re|re---| 代表两个小结,其中,第一个小结长度为 8,即 “do-do-re”;第二个小结长度为 5,即 “re---”。
随后,我们定义字符串的和声为:字符串和声小节数量和各个小结的长度均与原字符串一致,唯一的区别是其会比原字符串晚 p 个长度出现,和声未出现时使用下划线替代空白位置,小结结束时未输出完整的和声会被直接截断;更具体地,先在每一个小节前面加上 p 条下划线,随后截取原来的小节的长度位,得到每一个小节的和声。例如,当 p = 2 时,第一小节变为 “__do-do-re”,再截取前 8 位,得到第一小节的和声 “__do-do-”,上方式例的和声最终可以唯一地表示为 |__do-do-|__re-|。
现在,对于给出的字符串和整数 p,请你直接输出和声!
输入描述
第一行输入两个整数 n, p (1 ≤ n ≤ 3×10⁵; 0 ≤ p ≤ 10⁹) 代表原字符串总长度(包括 | 在内)和和声延迟的长度。
此后若干行,一共输入 n 个字符,代表原字符串。
保证每行的首末均为竖线(|),每个小结的长度至少为 1,小结中的字符仅为小写字母和连接线(-)。
输出描述
根据输入,输出若干行,代表和声字符串。
样例输入
16 2
|do-do-re|re---|
样例输出
|__do - do - |__re - |
参考题解
输入处理:读取总长度 n 和延迟值 p,逐行读取输入字符串,累加长度直至达到 n。 小节分割:按竖线 | 分割字符串,提取每个小节的内容。 生成和声:对每个小节,先添加 p 个下划线,再截取原小节的剩余部分,拼接成新的小节。 输出结果:将处理后的小节用竖线连接并输出。
C++:
#include <iostream>
#include <string>
using namespace std;
int main() {
int n, p;
cin >> n >> p;
int sum_len = 0;
while (sum_len < n) {
string s;
cin >> s;
sum_len += s.length();
string ans = "|";
int lst = 0;
for (int i = 1; i < s.length(); ++i) {
if (s[i] == '|') {
string seg = s.substr(lst + 1, i - lst - 1);
int t = min(int(seg.length()), p);
ans += string(t, '_') + seg.substr(0, seg.length() - t) + "|";
lst = i;
}
}
cout << ans << endl;
}
return 0;
}
Java:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int p = in.nextInt();
int sumLen = 0;
while (sumLen < n) {
String s = in.next();
sumLen += s.length();
StringBuilder ans = new StringBuilder("|");
int lst = 0;
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == '|') {
String seg = s.substring(lst + 1, i);
int t = Math.min(seg.length(), p);
// t 个 '_' 加上 seg 的前 (seg.length()-t) 个字符
for (int k = 0; k < t; k++) ans.append('_');
ans.append(seg, 0, seg.length() - t);
ans.append("|");
lst = i;
}
}
System.out.println(ans);
}
in.close();
}
}
Python:
def main():
import sys
data = sys.stdin.read().split()
# 先两个是 n、p,后面依次是各个 s
it = iter(data)
n = int(next(it))
p = int(next(it))
sum_len = 0
while sum_len < n:
s = next(it)
sum_len += len(s)
ans = ["|"]
lst = 0
for i, ch in enumerate(s[1:], start=1):
if ch == '|':
seg = s[lst+1:i]
t = min(len(seg), p)
# t 个 '_',再接 seg 前 len(seg)-t 个字符
ans.append("_" * t + seg[:len(seg)-t] + "|")
lst = i
# 把列表拼成字符串输出
sys.stdout.write("".join(ans) + "\n")
if __name__ == "__main__":
main()
第二题
将网格中的所有元素构成一维序列:先取出网格的第一行所有元素,按从左到右的顺序排列; 然后依次取出第二行、第三行,直到最后一行,同样每行按从左到右排列。 设一个网格对应的序列为S = [s1, s2, …, snm],另一个网格对应的序列为T = [t1, t2, …, tnm]。 我们定义:若存在最小的下标k(1≤k≤nm),使得对于所有1≤i < k有si = ti且sk < tk,则称序列S更小; 反之,若sk > tk,则序列S更大。若对于所有1≤i≤nm均有si = ti,则认为两个序列相等。 例如网格[[1, 2], [1, 1]]大于网格[[1, 1], [2, 1]],因为第一行的第二个元素2大于1。
输入描述
第一行输入两个正整数n,m(2≤n,m≤500),表示网格的大小。
接下来n行每一行输入m个正整数aij(1≤aij≤10^9)表示第i行第j列的权值。
输出描述
输出n行m列表示操作后的结果。
样例输入
2 3
1 3 2
4 6 5
样例输出
6 5 2
4 1 3
参考题解
输入解析:读取网格尺寸 n 和 m,将输入数据按奇偶位置分为两个数组。 排序处理:对奇偶数组分别降序排序。 重构网格:按原网格的奇偶位置交替从排序后的数组中取值,重构新的网格。 输出结果:逐行输出重构后的网格。
C++:
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<vector<int>> mat(n, vector<int>(m));
vector<int> eList, oList;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int v;
cin>>v;
mat[i][j]=v;
if(((i+j)&1)==0) eList.push_back(v);
else oList.push_back(v);
}
}
sort(eList.begin(), eList.end(), greater<int>());
sort(oList.begin(), oList.end(), greater<int>());
int p0=0, p1=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int v;
if(((i+j)&1)==0) v = eList[p0++];
else v = oList[p1++];
cout<<v;
if(j+1<m) cout<<' ';
}
cout<<"\n";
}
return 0;
}
Java:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
List<Integer> eList = new ArrayList<>();
List<Integer> oList = new ArrayList<>();
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
查看21道真题和解析