【春招笔试】2025.03.30-蚂蚁算法岗改编题

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺
  • 配套练习题库

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

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

春秋招合集 -> 互联网必备刷题宝典🔗

题目一:复制粘贴的艺术

1️⃣:通过枚举复制的位置,找到最优解

2️⃣:检查目标字符串前缀是否可以通过复制粘贴操作得到

3️⃣:根据具体情况计算最少操作次数

难度:中等

这道题目的关键在于发现可能的复制粘贴模式。当我们使用复制粘贴时,必须确保前k个字符等于接下来的k个字符。通过枚举可能的k值并计算相应的操作次数,我们可以找到最优解,算法复杂度为O(n²)。

题目二:网购行为分析系统

1️⃣:对用户行为数据进行最大最小归一化处理

2️⃣:使用特定公式计算用户行为得分

3️⃣:处理特殊情况并格式化输出结果

难度:中等

这道题目结合了数据处理和数学公式计算,要求对用户行为数据进行归一化处理并计算得分。关键是理解最大最小归一化的概念,正确处理边界情况,并按照指定格式输出结果。算法复杂度为O(n),其中n是用户数量。

题目三:字符串最大化连续字符

1️⃣:枚举保留的目标字符

2️⃣:使用双指针技术计算可能的最长连续序列

3️⃣:通过删除非目标字符,最大化连续字符长度

难度:中等

这道题目要求通过删除恰好k个字符,使剩余字符串的连续度最大。核心思路是枚举每种字符作为保留目标,使用双指针方法找出可以形成的最长连续序列。算法复杂度为O(26n),即O(n),其中n是字符串长度。

01. 复制粘贴的艺术

问题描述

A小姐最近在学习一款文本编辑器,她发现这款编辑器有两种特殊操作:

  1. 在文本末尾添加任意一个字符。
  2. 复制整个当前文本,然后将复制的内容粘贴到文本末尾。

A小姐很好奇,如果她一开始拥有一个空白文档,那么最少需要多少次操作才能得到她想要的目标文本呢?需要注意的是,复制粘贴这个操作在整个过程中最多只能使用一次。

输入格式

输入一个字符串 ,表示A小姐想要得到的目标文本,长度不超过

输出格式

输出一个整数,表示最少需要的操作次数。

样例输入

ababababc

样例输出

6

数据范围

样例 解释说明
ababababc 首先添加4个字符得到"abab",然后使用复制粘贴操作得到"abababab",最后添加字符'c',总共需要4+1+1=6次操作

题解

这道题目乍看之下可能有点复杂,但其实我们可以通过分析操作的特性来找出规律。

首先,如果我们不使用复制粘贴操作,那么我们需要的操作次数就等于目标字符串的长度,因为我们需要一个一个地添加每个字符。

但如果我们使用复制粘贴操作,就可能减少总的操作次数。关键是要找出复制粘贴的最佳时机。

想象一下,假设我们已经构建了前 个字符,然后使用了复制粘贴操作,那么我们会得到这 个字符的重复,即总共 个字符。为了使这个操作有效,这 个字符必须是目标字符串的前 个字符的一部分,也就是说前 个字符必须等于接下来的 个字符。

所以,我们可以枚举所有可能的 值(从1到 ),检查是否满足 。如果满足,那么我们可以通过以下步骤构建目标字符串:

  1. 添加前 个字符,需要 次操作
  2. 使用一次复制粘贴操作,得到 个字符
  3. 继续添加剩余的 个字符

总操作次数为

我们需要找出使得这个表达式最小的 值,即使得 尽可能大的值。但记住, 必须满足

时间复杂度分析:我们枚举 的值,对于每个 ,需要比较两个长度为 的子串,这需要 的时间。总的时间复杂度为 ,其中 是目标字符串的长度。考虑到 最大为1000,这个算法是足够高效的。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

# 获取目标字符串
s = input()
n = len(s)

# 默认答案为不使用复制粘贴的情况
ans = n

# 枚举可能的复制长度
for k in range(1, n // 2 + 1):
    # 检查前k个字符是否等于接下来的k个字符
    if s[:k] == s[k:2*k]:
        # 计算总操作次数:k次添加 + 1次复制粘贴 + (n-2k)次添加剩余字符
        ops = k + 1 + (n - 2 * k)
        ans = min(ans, ops)

print(ans)
  • Cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    cin >> s;
    int n = s.size();
    
    // 默认答案为字符串长度
    int ans = n;
    
    // 枚举复制长度k
    for (int k = 1; k <= n/2; k++) {
        // 判断前k个字符是否等于接下来的k个字符
        if (s.substr(0, k) == s.substr(k, k)) {
            // 计算操作次数
            int tmp = k + 1 + (n - 2*k);
            ans = min(ans, tmp);
        }
    }
    
    cout << ans << endl;
    return 0;
}
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int n = s.length();
        
        // 默认答案为字符串长度
        int ans = n;
        
        // 枚举可能的复制长度
        for (int k = 1; k <= n/2; k++) {
            // 检查是否满足复制条件
            if (s.substring(0, k).equals(s.substring(k, 2*k))) {
                // 计算操作次数
                int ops = k + 1 + (n - 2*k);
                ans = Math.min(ans, ops);
            }
        }
        
        System.out.println(ans);
        sc.close();
    }
}

02. 网购行为分析系统

问题描述

小柯是一家大型电商平台的数据分析师,她需要设计一个系统来评估用户的购物行为,以便为用户提供更个性化的推荐服务。经过调研,她发现用户的行为主要可以通过三个指标来量化:点击次数(clicks)、浏览时间(duration)和购买次数(purchases)。

为了更科学地评估用户行为,小柯设计了一个行为得分计算公式,需要先对这三个指标进行归一化处理,然后根据特定的公式计算最终得分。

你的任务是帮助小柯实现这个评分系统,根据输入的用户行为数据计算每个用户的行为得分。

输入格式

输入是一个字典,键是用户的 (字符串),值是一个字典,包含 ""、""、"" 三个键,分别代表用户的点击次数、停留时间、购买次数(均为整数)。

输出格式

返回一个字典,格式与输入相同,但是输出每个用户的行为得分。

样例输入

{"user1":{"clicks":10,"duration":3600,"purchases":2},"user2":{"clicks":20,"duration":7200,"purchases":1},"user3":{"clicks":30,"duration":10800,"purchases":0}}

样例输出

{user1":{"score":2.0},"user2":{"score":2.429},"user3":{"score":3.411}}

数据范围

  • 用户数量范围:
  • 点击次数范围:
  • 浏览时间范围: (单位:秒)
  • 购买次数范围:
样例 解释说明
样例1 首先对所有用户的三个指标进行最大最小归一化,然后根据公式 计算每个用户的得分,结果四舍五入保留至多3位小数

题解

这道题目看起来有点复杂,但其实思路很清晰,主要分为两个步骤:数据归一化和得分计算。

首先,什么是最大最小归一化?简单来说,就是将数据线性变换到[0,1]区间内,变换公式为:

特别地,当所有值都相等时(即最大值=最小值),归一化结果就是0。

对于本题,我们需要对每个特征(clicks、duration、purchases)分别进行归一化处理。具体步骤如下:

  1. 读取输入数据并解析为字典格式
  2. 收集所有用户的三个特征值,找出每个特征的最大值和最小值
  3. 使用最大最小归一化公式,计算每个用户每个特征的归一化值
  4. 根据给定的公式计算得分:
  5. 将结果四舍五入保留至多3位小数

需要注意的是,题目还有一个特殊情况:当所有用户的clicks、duration和purchases都为0时,应该返回"NaN"作为得分。这是因为在这种情况下,我们无法进行有意义的归一化和比较。

关于计算公式的设计,它综合考虑了三个特征的不同影响:

  • 对点击次数使用对数函数,可以降低高点击量的权重,使得评分不会因极端值而失真
  • 对浏览时间使用指数函数,可以强调长时间浏览的重要性
  • 对购买次数使用二次项,表明购买行为是最有价值的指标

时间复杂度分析:我们需要遍历所有用户两次,一次是为了找出特征的最大最小值,另一次是为了计算得分。因此总体时间复杂度为O(n),其中n是用户数量。考虑到用户数最多为1000,这个算法效率很高。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()
import json
import math

# 从终端读取输入
input_str = input()
data = json.loads(input_str)

# 检查是否所有数据都为0
all_zero = True
for user, info in data.items():
    if info['clicks'] > 0 or info['duration'] > 0 or info['purchases'] > 0:
        all_zero = False
        break

# 如果全为0则返回NaN
if all_zero:
    res = {user: {"score": "NaN"} for user in data}
    print(json.dumps(res))
    exit()

# 提取各特征的值列表
clk = [info['clicks'] for info in data.values()]
dur = [info['duration'] for info in data.values()]
pur = [info['purchases'] for info in data.values()]

# 计算最大最小值
min_c, max_c = min(clk), max(clk)
min_d, max_d = min(dur), max(dur)
min_p, max_p = min(pur), max(pur)

# 计算每个用户的得分
result = {}
for uid, info in data.items():
    # 归一化处理
    nc = 0 if max_c == min_c else (info['clicks'] - min_c) / (max_c - min_c)
    nd = 0 if max_d == min_d else (info['duration'] - min_d) / (max_d - min_d)
    np = 0 if max_p == min_p else (info['purchases'] - min_p) / (max_p - min_p)
    
    # 按公式计算得分
    scr = math.log(1 + nc) + math.exp(nd) + np * (np + 1) / 2
    result[uid] = {"score": round(scr, 3)}

# 输出结果
print(json.dumps(result))
  • Cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;

int main() {
    // 注意:真实环境中需要正确解析JSON,这里简化处理
    string json_str;
    getline(cin, json_str);
    
    // 假设我们已经解析出了用户数据
    map<string, map<string, int>> data = {
        {"user1", {{"clicks", 10}, {"duration", 3600}, {"purchases", 2}}},
        {"user2", {{"clicks", 20}, {"duration", 7200}, {"purchases", 1}}},
        {"user3", {{"clicks", 30}, {"duration", 10800}, {"purchases", 0}}}
    };
    
    // 检查是否所有值都为0
    bool all_zero = true;
    for (auto& [uid, vals] : data) {
        if (vals["clicks"] > 0 || vals["dura

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

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务