阿里云笔试 阿里云笔试题 研发岗 0511

笔试时间:2025年5月11日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

小歪正在学习字符串和声,字符串仅由小写字母和连接线‘-’构成。我们使用竖线‘|’来划分小结,例如,|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 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

09-22 09:15
已编辑
安徽理工大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务