10.19京D(已改编)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试

💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历

✨ 本系列打算持续跟新 春秋招算法题

👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸

✨ 算法合集传送们 -> 🧷学长刷题笔记

🍒 本专栏已收集 140+ 套题,算法题 会在第一时间跟新

🍄 题面描述等均已改编,如果和你笔试题看到的题面描述不一样请理解,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞

alt

🧸 本次前两题比较简单,第三题难度较大,

1️⃣ 简单的字符串模拟,考察语法

2️⃣ 大根堆的应用,也可以上别的动态求第K大的数据结构

3️⃣ 二分+动态规划,二分的 check 比较难想,需要用DP来实现,难度较大

🧸 01.LYA的文字过滤器 评测链接🔗

问题描述

LYA是一个热爱交流的大学生,她创建了一个在线讨论平台,希望同学们能在这里自由地交流学习心得。然而,随着平台用户的增多,一些不当言论开始出现,影响了平台的和谐氛围。为了维护良好的讨论环境,LYA决定开发一个文字过滤器,用于自动检测和替换敏感词。

这个文字过滤器的工作原理如下:

  1. 首先,LYA会提供一个敏感词库,包含多个需要过滤的词汇。
  2. 当用户发送消息时,系统会检查消息中是否包含敏感词库中的任何词汇。
  3. 如果发现敏感词,系统会将其替换为等长的星号(*)。
  4. 替换过程是贪婪的,即如果一个子串匹配多个敏感词,会选择最长的那个进行替换。

LYA希望你能帮她实现这个文字过滤器,让平台重新变得和谐友好。

输入格式

第一行包含一个整数 ,表示敏感词库中的词汇数量。

第二行是一个字符串 ,表示需要处理的用户消息。

接下来的 行,每行包含一个字符串 ,表示一个敏感词。

输出格式

输出一行,表示经过文字过滤器处理后的消息。

样例输入1

3
iakioi
ki
io
qwq

样例输出1

ia***i

样例解释

样例 解释说明
样例1 敏感词库包含三个词:"ki"、"io"和"qwq"。在输入字符串"iakioi"中,"ki"和"io"都是敏感词。系统先将"ki"替换为"",然后将"io"替换为""。由于两个敏感词有重叠,最终结果是将"kio"整体替换为"***"。

数据范围

  • 所有字符串只包含小写英文字母

题解

字符串模拟

这道题目要求我们实现一个简单的文字过滤系统。虽然看起来不难,但其中还是有一些细节需要注意。

理解题目的核心要求:

  1. 有一个敏感词库和一个需要处理的字符串。
  2. 需要在字符串中找出所有的敏感词,并将它们替换为等长的星号。
  3. 如果有重叠的敏感词,需要选择最长的那个进行替换。

解决这个问题的一个直观思路是:

  1. 遍历字符串的每个位置。
  2. 对于每个位置,检查是否有以该位置开始的敏感词。
  3. 如果找到敏感词,就将其替换为星号,然后继续处理下一个未被替换的字符。

这个方法的时间复杂度是 ,其中 是字符串长度, 是敏感词的数量, 是敏感词的最大长度。对于给定的数据范围(),这个复杂度是可以接受的。

参考代码

  • Python
# 读取输入
n = int(input())  # 敏感词数量
s = input()  # 需要处理的字符串
sensitive_words = set(input() for _ in range(n))  # 敏感词集合

# 将字符串转换为列表,方便修改
s_list = list(s)

# 遍历字符串的每个位置
i = 0
while i < len(s):
    # 检查从当前位置开始的所有可能的子串
    for j in range(min(5, len(s) - i), 0, -1):
        if s[i:i+j] in sensitive_words:
            # 如果找到敏感词,替换为星号
            s_list[i:i+j] = ['*'] * j
            i += j - 1
            break
    i += 1

# 将列表转回字符串并输出
print(''.join(s_list))
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        int n = scanner.nextInt();
        scanner.nextLine();  // 消耗换行符
        String s = scanner.nextLine();
        Set<String> sensitiveWords = new HashSet<>();
        for (int i = 0; i < n; i++) {
            sensitiveWords.add(scanner.nextLine());
        }
        
        // 处理字符串
        StringBuilder result = new StringBuilder(s);
        for (int i = 0; i < result.length(); i++) {
            for (int j = Math.min(5, result.length() - i); j > 0; j--) {
                if (sensitiveWords.contains(result.substring(i, i + j))) {
                    for (int k = i; k < i + j; k++) {
                        result.setCharAt(k, '*');
                    }
                    i += j - 1;
                    break;
                }
            }
        }
        
        // 输出结果
        System.out.println(result.toString());
    }
}
  • Cpp
#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;

int main() {
    int n;
    string s;
    unordered_set<string> sensitive_words;

    // 读取输入
    cin >> n;
    cin.ignore();  // 忽略换行符
    getline(cin, s);
    for (int i = 0; i < n; i++) {
        string word;
        getline(cin, word);
        sensitive_words.insert(word);
    }

    // 处理字符串
    for (int i = 0; i < s.length(); i++) {
        for (int j = min(5, (int)s.length() - i); j > 0; j--) {
            if (sensitive_words.count(s.substr(i, j))) {
                fill(s.begin() + i, s.begin() + i + j, '*');
                i += j - 1;
                break;
            }
        }
    }

    // 输出结果
    cout << s << endl;

    return 0;
}

🪴 02.卢小姐的珍珠排序 评测链接🔗

问题描述

卢小姐是一位珠宝设计师,她最近收到了一批珍珠,准备用来制作一条精美的项链。这些珍珠按照大小排列在一个长度为 的序列中,编号从 。卢小姐想要了解在制作过程中,每添加一颗珍珠后,当前已使用珍珠中第 小的珍珠是哪一颗。

为了帮助卢小姐完成这个任务,我们需要编写一个程序。对于每个位置 ),我们需要找出前 颗珍珠中第 小的珍珠的大小。如果当前使用的珍珠数量不足 颗,则输出

输入格式

第一行包含两个整数 ),分别表示珍珠的总数量和我们需要找的第 小的珍珠。

第二行包含 个整数 ),表示每颗珍珠的大小。保证所有 互不相同。

输出格式

输出一行,包含 个整数,以空格分隔。第 个数表示前 颗珍珠中第 小的珍珠的大小。如果前 颗珍珠的数量不足 个,则输出

样例输入1

5 2
5 4 3 2 1

样例输出1

-1 5 4 3 2

样例输入2

6 3
2 4 6 1 3 5

样例输出2

-1 -1 4 4 3 3

样例解释

样例 解释说明
样例1 对于前1颗珍珠,数量不足2个,输出-1。
对于前2颗珍珠[5,4],第2小的是5。
对于前3颗珍珠[5,4,3],第2小的是4。
对于前4颗珍珠[5,4,3,2],第2小的是3。
对于全部5颗珍珠[5,4,3,2,1],第2小的是2。
样例2 对于前1和前2颗珍珠,数量不足3个,输出-1。
对于前3颗珍珠[2,4,6],第3小的是6。
对于前4颗珍珠[2,4,6,1],第3小的是4。
对于前5颗珍珠[2,4,6,1,3],第3小的是3。
对于全部6颗珍珠[2,4,6,1,3,5],第3小的是3。

数据范围

  • 所有 互不相同

题解

大根堆

这道题目要求我们在不断添加新元素的过程中,动态地找出第 小的元素。这个问题可以通过维护一个大小为 的大根堆来高效解决。

解题思路如下:

  1. 初始化一个大根堆,用于存储当前最小的 个元素。

  2. 遍历数组 ,对于每个元素

    • 如果堆的大小小于 ,直接将 加入堆中。
    • 如果堆的大小等于 ,比较 与堆顶元素:
      • 如果 小于堆顶元素,弹出堆顶元素,并将 加入堆中。
      • 否则,不做任何操作。
  3. 在每一步后,如果堆的大小等于 ,则堆顶元素就是当前第 小的数;否则,输出

这个方法的关键在于,只需要维护最小的 个元素,而不需要对所有元素进行排序。大根堆能够保证堆顶元素始终是这 个元素中的最大值,也就是第 小的元素。

时间复杂度分析:

  • 对于每个元素,我们最多进行一次堆的插入或删除操作,这些操作的时间复杂度为
  • 总共有 个元素,因此总的时间复杂度为

考虑到 ,这个时间复杂度是可以接受的。

空间复杂度为 ,用于存储堆中的元素。

参考代码

  • Python
import heapq

def find_kth_smallest(n, k, arr):
    heap = []
    result = []
    
    for num in arr:
        # 如果堆的大小小于k,直接添加
        if len(heap) < k:
            heapq.heappush(heap, -num)  # 使用负数来模拟大根堆
        # 如果当前数小于堆顶元素,更新堆
        elif -num > heap[0]:
            heapq.heapreplace(heap, -num)
        
        # 输出结果
        if len(heap) < k:
            result.append(-1)
        else:
            result.append(-heap[0])
    
    return result

# 读取输入
n, k = map(int, input().split())
arr = list(map(int, input().split()))

# 计算结果并输出
result = find_kth_smallest(n, k, arr)
print(*result)
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n 

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

本专栏短期内不再更新,请勿继续订阅

全部评论
最后一个组战队的题有吗,我就那题做不出来
点赞 回复 分享
发布于 2024-10-21 16:39 湖北

相关推荐

我曾经以为实习第一天离职,听上去很不可思议,甚至像是小说中的剧情,但是这种事情真的发生在了我身上。在5月23日,我参加了一个中小厂的面试,一面非常的顺利,大部分问题我都成功回答出来了,到了后面反问环节,还知道了面试官居然是我的学长,这让我非常亲切。当天hr就约我进行二面了,我当时感觉自己好幸运,好幸福。hr给我说二面的面试官可能会比较严厉,但是私下人很好(划重点!)时间来到了5月25日,我二面的日子,我家住重庆主城的南边,公司在北边,我单程的通勤时间是2h左右。二面很艰难,比一面难了许多,全是上一段实习的项目拷打和场景题,我当时压力很大,感觉很不适(可能是我没有被这么压力面过),但是我没有觉得面试官有什么问题,或者这个方式有什么不妥,我只是觉得自己还很菜,对于这方面的准备还需要加强。然后就在这样的煎熬中,我度过了二面。hr姐姐是个很好的人,她一直在帮我跟进二面的进度,也一直在给我反馈,在5月26日晚,hr给我说二面过了,让我准备学信网在线认证的资料等,我当时觉得那是我人生中最快乐的几个瞬间之一。5月26日到6月4日,可能是我大学生涯中过得最像一个普通的二本男大学生的日子:天天睡到自然醒,到了实验室就躺着玩手机,玩累了就晚电脑,然后隔三岔五就出去吃顿好的(当然,没有说这样的生活不好的意思),然后就到了今天,6月5日,我入职——和我离职的日子。6月5日,早上5:55,重庆很多高中走读生起床的时间,我也起床了,因为通勤需要两个小时,加上是入职的日子,我决定早点到公司。重庆的直快列车,早上是没有位置的,我背着我的游戏本站了一个多小时,加上步行1.5km,终于在8:27分到了公司大厅,然后在9:00过,被一个同事带到了工位上,工位左边的就是我的学长,右边的是一个大四的同事。由于我们的项目是银行的内网开发,需要安装一系列银行内网的软件和配置一系列的环境。两个同事都非常热心的一直在帮助我,终于在十点过,配置到了最后一步,安装银行的一个什么安全助手,安装后就出问题了:“我的conda被列为了高危软件,需要立即卸载”(虽然我不知道为什么conda是高危软件),但是我conda配置了很多虚拟环境,我不是很想删除。于是我和几个同事商量了之后,我决定使用公司电脑进行环境配置。但是现在有个严重的问题:“因为我的conda被列为了高危软件,导致银行的安全助手把我的网断了”(我不知道是什么原理,可以让我无法上网,请原谅我的垃圾计网),更逆天的是,这个安全助手一旦安装则无法卸载,并且永久启动。此时我的想法是&quot;我反正向公司申请了电脑,那得先把我的电脑搞好,把conda卸载了,先有网了再说。&quot;然后我就开始卸载conda,因为我的环境什么的很多,conda卸载得很慢,此时,二面面试官——也就是我们的项目经理,也就是这个故事的男二号他来了,他一进门就对着我说“你一天没得事干得迈?怎么坐起在耍哎?”我当时就懵了,我在等待conda卸载,此时我的电脑是没有网的,我什么也干不了,我只能盯着屏幕上面的进度条,不然我还可以耍手机。但是处于礼貌和下属的身份,我还是用认错的口吻回了一个“有事做,有事做”。本以为风波就会过去,但是我卸载conda后,软件依旧在报错,我的电脑依旧没有网。此时我的两个“同桌”仍然不厌其烦的帮我想办法解决,我的目光也就在他们两个的电脑上面来回跳动,这个时候,他又开始发狂了:“xx(我学长的名字),你没有给他安排任务吗?我感觉他一直没得事做得哎,你把下周要做的给他安排起啊!”,此时我已经有些厌烦,就没有理他,而我的学长非常耐心的给他解释了今天早上发生了什么事情和为什么我看起来无所事事。(真的感谢学长)但是搞了很久,还是没有解决这个问题,我们都有些无语了,特别是我,看到电脑被一个“流氓软件”搞得上不了网,就好像影视作品中无能的丈夫一样无力,我十分烦躁,此时,他点燃了我:“xxx(我的大名),下次就不可能让你因为自己的原因,上班来搞这些了哈,搞不好自己加班给我搞!”我当时就发火了,原因有两点:1、这根本不是我的问题啊,我怎么知道电脑里面有些看起来很日常的软件和内网的软件不兼容;2、我明明一直在解决问题,他什么都不知道但是却一直说我,还指着我说这些都来了。然后我就怼了回去,怼了他几句,他就说不出话了——“可能是不想和我计较吧,大概!”。中午吃饭的时候,整个项目组都很震惊,好像我是第一个怼他的,然后大家在一起吃饭的时候都在骂他,说他让整个团队变得非常压抑,他非常不讲道理,他就是这种人什么的。大家都在安慰我(这里非常感谢大家),但是我已经决定今天就离职!到了下班时间,气氛非常的微妙,大家都归心似箭,但是却无一人起身,这是为什么?——因为他要加班!是的,就是因为他要加班,没有一个人敢走!但是我已决心离职,于是收好东西之后,郑重的和我的学长还有旁边的同事告别后,扬长而去。到了地铁站我就给hr提出离职,hr主动和我打电话了解了情况,并且耐心的安慰我(这里非常感谢hr姐姐,如果她可以看到的话,衷心表示感谢);学长也给我发消息安慰我,让我冷静一下。现在,也已经深了,我相当的冷静,我还是决定离职,我不知道这是否是一个好的选择,至少在当下,大三的我觉得这是一个必要的,正确的选择!我也相当的后悔,我只是怼回去了,而我并没有骂他,相当的后悔!最后,再次衷心感谢hr姐姐、我的学长、我的同桌、和项目组中帮助过我的每一个人。(给大家一个面子,也不给大家找麻烦,我决定不曝光公司名和他的名字)
大三一定要找到实习:后悔啥呀,通勤2h➕第一天被疯狂压力➕加班,这日子后面会很难受
实习生的蛐蛐区
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

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