蚂蚁笔试 蚂蚁笔试题 0508

笔试时间:2025年5月8日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:Y串

对于给定的字符串 S1S2…Sn​,将其全部奇数位置的字符删除,得到新的字符串 S′,随后将 S′ 反转,得到新的字符串 S′′,最后,将 S′′中的所有小写字母转换为大写字母。

你需要输出最终得到的字符串 S′′。

输入描述

第一行输入一个长度为 1≤len(S)≤105,由大小写字母混合构成的字符串 S。

输出描述

输出最终得到的字符串 S′′。

样例输入

WhilE

样例输出

LH

第一步,删除奇数位置的字符,得到新的字符串S'="hl";

第二步,反转字符串,得到新的字符串S''="lh";

第三步,将S''中的所有小写字母转换为大写字母,得到最终的字符里S''="LH"

参考题解

签到题,模拟即可。先删除奇数位置,得到新字符串,之后将其反转,最后小写转大写即可。

C++:

#include<bits/stdc++.h>
usingnamespacestd;
int main() {
    string s;
    cin >> s;
    string t;
    for (int i = 1; i < s.length(); i += 2) {
        t += s[i];
    }
    reverse(t.begin(), t.end());
    for (char& c : t) {
        if (islower(c)) {
            c = toupper(c);
        }
    }
    cout << t;
}
 

Java:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        StringBuilder t = new StringBuilder();

        // 提取每隔一个字符
        for (int i = 1; i < s.length(); i += 2) {
            t.append(s.charAt(i));
        }

        // 反转字符串
        t.reverse();

        // 转换小写字母为大写
        for (int i = 0; i < t.length(); i++) {
            if (Character.isLowerCase(t.charAt(i))) {
                t.setCharAt(i, Character.toUpperCase(t.charAt(i)));
            }
        }

        System.out.println(t);
    }
}

Python:

def main():
    s = input()
    t = ''

    # 提取每隔一个字符
    for i in range(1, len(s), 2):
        t += s[i]

    # 反转字符串
    t = t[::-1]

    # 转换小写字母为大写
    t = ''.join([char.upper() if char.islower() else char for char in t])

    print(t)

if __name__ == "__main__":
    main()

第二题:小红的查询线段

小红有一根长度为 n 的绳子,她在绳子上均匀地画了 n 个点(包括端点),点的编号为 1 ~ n,这样绳子被均分为 n 段。

她现在提出 Q 次查询,每次查询要进行下列操作的其中一种:

操作一:在点 a (1 ≤ a ≤ n) 上画一条红线。

操作二:若把当前画红线的地方全部删掉,询问是否存在长度大于等于 k 的绳子。

不考虑绳子损坏且每次询问都是独立(即假设绳子断裂,但实际上并不是真的断裂),请你回答小红的每次询问。

输入描述

第一行输入两个整数 n, Q (3 ≤ n ≤ 10^9; 1 ≤ Q ≤ 10^5) 代表绳子的长度,小红的操作查询次数。

接下来 Q 行,每行先输入一个整数 op (1 ≤ op ≤ 2) 表示操作查询的类型,随后:

当 op = 1,在后续一行输入一个整数 a (1 ≤ a ≤ n),表示在 x 处画一条红线。

当 op = 2,在后续一行输入一个整数 k (1 ≤ k ≤ 10^9) 查询若把当前的红线断开,是否存在长度大于等于 k 的绳子的长度。

输出描述

对于每个询问二,若把当前的红线剪断,会存在长度大于等于k的绳子,在一行上输出YES ;否则,直接输出NO。

样例输入

8 7

2 7

1 4

2 4

2 5

1 6

2 3

2 4

样例输出

YES

YES

NO

YES

NO

初始时绳子形象的表示为1-2-3-4-5-6-7-8;

对于第一次操作,由于此前没有画过红线,所以得到一根长度为7的绳子,符合询问;

对于第二次操作,在第四个点的位置画一条红线,得到1-2-3-[4]-5-6-7-8;

对于第三次操作,切断后得到一根长度为3的绳子和一很长度为4的绳子,1-2-3-4和4-5-6-7-8,符合询问;

对于第四次操作,同上,不符合询问:

对于第五次操作,在第六个点的位置画一条红线,得到1-2-3-[4]-5-[6]-7-8;

对于第六次操作,切断后得到一根长度为3的绳子和两根长度为2的绳子,1-2-3-4、4-5-6和6-7-8,符合询问。

参考题解

set+map,利用set维护所有红线的位置,利用map维护每种长度绳子出现的数量。对于操作一,在x处画一条红线,假如x已在set中,说明之前画过红线则跳过。否则在set中二分小于x且最大的红线位置记作lc,大于x且最小的红线记作rc。那么原来的长度rc-lc会被切断成x-lc和rc-x两段,在map中更新对应数量。对于操作二,直接看map中最大的那个长度是否大于等于k即可。

C++:

#include <bits/stdc++.h>
usingnamespacestd;
int main() {
    int n, q;
    cin >> n >> q;
    set<int> st;
    map<int, int> mp;
    mp[n - 1] = 1;
    while (q--) {
        int op;
        cin >> op;
        if (op == 1) {
            int x;
            cin >> x;
            x--;
            if (st.find(x) != st.end()) {
                continue;
            }
            int lc = 0;
            auto it_lc = st.upper_bound(x);
            if (it_lc != st.begin()) {
                --it_lc;
                lc = *it_lc;
            }
            int rc = n - 1;
            auto it_rc = st.upper_bound(x);
            if (it_rc != st.end()) {
                rc = *it_rc;
            }
            int sz = rc - lc;
            auto map_it = mp.find(sz);
            if (map_it != mp.end()) {
                if (--map_it->second == 0) {
                    mp.erase(map_it);
                }
            }
            mp[x - lc]++;
            mp[rc - x]++;
            st.insert(x);
        } else {
            int k;
            cin >> k;
            if (mp.empty() || mp.rbegin()->first < k) {
                cout << "NO\n";
            } else {
                cout << "YES\n";
            }
        }
    }
}

Java:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int q = sc.nextInt();
        
        Set<Integer> st = new TreeSet<>();
        Map<Integer, Integer> mp = new HashMap<>();
        mp.put(n - 1, 1);

        while (q-- > 0) {
            int op = sc.nextInt();

            if (op == 1) {
                int x = sc.nextInt();
                x--;

                // 如果 x 已经存在,则跳过
                if (st.contains(x)) {
                    continue;
                }

                int lc = 0;
             

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

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

全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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