阿里云笔试 阿里云笔试题 研发岗 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等多种语言做法集合指南