【秋招笔试】9.01字节跳动秋招(已改编)-三语言题解

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

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

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

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

✨ 笔试合集传送们 -> 🧷春秋招笔试合集

🍒 本专栏已收集 90+ 套笔试题,笔试真题 会在第一时间跟新

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

🧩 备战秋招还没订阅的朋友们可以冲一下啦,当试题收集至 100 套后,价格会进行一波调整~

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

alt

🪔 字节跳动的秋招笔试,来啦!!!

🍥 本次的代码难度都不大,主要是思维题

1️⃣ 比较简单,可以前后缀预处理或者直接上数据结构

2️⃣ 数学思维题,对原本的等式做下变形即可

3️⃣ 思维题+数论相关

4️⃣ 动态规划,需要用二分或者树状数组优化

🎀 01.LYA的彩色画布

问题描述

LYA是一位热爱艺术的年轻画家。她最近得到了一块特殊的画布,这块画布被分成了 个小格子。每个格子都有一个独特的色彩值。LYA想要创作一幅独特的作品,她决定选择一个分界点 ,将分界点左边(包括分界点)的格子涂成红色,右边的格子涂成蓝色。

LYA希望她的作品能够呈现出和谐的美感。她定义了一个"和谐度"的概念:红色区域的色彩极差(最大值减最小值)与蓝色区域的色彩极差的差的绝对值。LYA想要找到一个分界点,使得这个"和谐度"最小。你能帮助LYA找到这个最小的"和谐度"吗?

输入格式

第一行输入一个整数 ,表示画布的格子数。

第二行输入 个整数 ,表示每个格子的色彩值。

输出格式

输出一个整数,表示最小的"和谐度"。

样例输入

5
1 2 4 3 5

样例输出

1

样例解释

当选择 时,红色区域为 ,极差为 ;蓝色区域为 ,极差为 。"和谐度"为 ,这是所有可能分界点中的最小值。

数据范围

题解

维护一个前缀最大和最小,以及后缀的最大和最小值即可。

这里为了方便直接用数据结构写了,时间复杂度会多带一个log

参考代码

  • Python
from sortedcontainers import SortedList

def main():
    # 读取输入
    n = int(input())
    a = list(map(int, input().split()))
    
    # 初始化左右两个SortedList
    left = SortedList()
    right = SortedList(a)
    
    res = float('inf')
    
    # 遍历数组
    for i in range(n - 1):
        # 将当前元素从右侧移到左侧
        curr = right.pop(right.index(a[i]))
        left.add(curr)
        
        # 如果右侧为空,跳出循环
        if not right:
            break
        
        # 计算左右两侧的极差
        left_range = left[-1] - left[0]
        right_range = right[-1] - right[0]
        
        # 更新结果
        res = min(res, abs(left_range - right_range))
    
    # 输出结果
    print(res)

if __name__ == "__main__":
    main()
  • Java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] a = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        
        // 使用TreeMap来模拟多重集
        TreeMap<Integer, Integer> left = new TreeMap<>();
        TreeMap<Integer, Integer> right = new TreeMap<>();
        
        // 初始化右侧多重集
        for (int num : a) {
            right.put(num, right.getOrDefault(num, 0) + 1);
        }
        
        int res = Integer.MAX_VALUE;
        
        for (int i = 0; i < n - 1; i++) {
            // 将当前元素从右侧移到左侧
            left.put(a[i], left.getOrDefault(a[i], 0) + 1);
            right.put(a[i], right.get(a[i]) - 1);
            if (right.get(a[i]) == 0) right.remove(a[i]);
            
            // 计算左右两侧的极差
            int leftRange = left.lastKey() - left.firstKey();
            int rightRange = right.lastKey() - right.firstKey();
            
            // 更新结果
            res = Math.min(res, Math.abs(leftRange - rightRange));
        }
        
        System.out.println(res);
    }
}
  • Cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int n;
    cin >> n;
    vector<int> a(n);
    
    // 使用multiset来存储左右两侧的元素
    multiset<int> left, right;
    
    // 读取输入并初始化右侧multiset
    for (int& x : a) {
        cin >> x;
        right.insert(x);
    }
    
    int res = INT_MAX;
    
    // 遍历数组
    for (int i = 0; i < n - 1; ++i) {
        // 将当前元素从右侧移到左侧
        left.insert(a[i]);
        right.erase(right.find(a[i]));
        
        // 计算左右两侧的极差
        int left_range = *left.rbegin() - *left.begin();
        int right_range = *right.rbegin() - *right.begin();
        
        // 更新结果
        res = min(res, abs(left_range - right_range));
    }
    
    // 输出结果
    cout << res << "\n";
    
    return 0;
}

🚙 02.K小姐的珠宝配对

问题描述

K小姐是一位珠宝设计师,她最近收到了一批特殊的宝石。这批宝石共有 颗,每颗宝石都有一个独特的魔力值。K小姐想要将这些宝石制作成一系列成对的耳环。

她发现,当两颗宝石的魔力值之和等于它们在序列中的位置之和时,这对宝石就能产生奇妙的共鸣效果。K小姐想知道在这批宝石中,有多少对宝石可以形成这种奇妙的共鸣。

具体来说,如果第 颗宝石和第 颗宝石满足 (其中 表示第 颗宝石的魔力值),那么这对宝石就可以形成一对完美的耳环。

请你帮K小姐计算一下,这批宝石中有多少对可以形成完美的耳环。

输入格式

输入包含两行。

第一行是一个正整数 ),表示宝石的数量。

第二行包含 个正整数 ),表示每颗宝石的魔力值。保证输入的魔力值序列是一个 的排列。

输出格式

输出一行,包含一个整数,表示可以形成完美耳环的宝石对数。

样例输入

5
2 1 3 5 4

样例输出

4

样例解释

在这个例子中,以下四对宝石可以形成完美的耳环:

  1. 第 1 颗和第 2 颗:
  2. 第 2 颗和第 4 颗:
  3. 第 1 颗和第 5 颗:
  4. 第 4 颗和第 5 颗:

数据范围

题解

这道题的核心在于如何高效地找出满足条件的宝石对。

一个直观的想法是遍历所有可能的对,但这样的时间复杂度是 ,对于给定的数据范围来说太高了。

可以通过数学变换来简化问题。

对于任意一对满足条件的宝石 ,有:

移到等式右边:

这意味着,如果我们计算每个宝石的 值,那么满足条件的一对宝石的这个值之和应该为 0。

因此,可以使用哈希表来存储每个 值出现的次数。

遍历一遍数组,对于每个宝石,检查 是否在哈希表中,如果在,就将其出现次数加到结果中。然后将当前的 加入哈希表。

参考代码

  • Python
def main():
    # 读取宝石数量
    n = int(input())
    # 读取每颗宝石的魔力值
    p = list(map(int, input().split()))
    
    # 初始化结果和哈希表
    res = 0
    diff_count = {}
    
    # 遍历每颗宝石
    for i in range(n):
        # 计算 p[i] - (i+1)
        diff = p[i] - (i + 1)
        # 检查是否存在匹配的宝石
        if -diff in diff_count:
            res += diff_count[-diff]
        # 更新哈希表
        diff_count[diff] = diff_count.get(diff, 0) + 1
    
    # 输出结果
    print(res)

if __name__ == "__main__":
    main()
  • Java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 读取宝石数量
        int n = Integer.parseInt(br.readLine());
        // 读取每颗宝石的魔力值
        int[] p = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        
        // 初始化结果和哈希表
        long res = 0;
        Map<Integer, Integer> diffCount = new HashMap<>();
        
        // 遍历每颗宝石
        for (int i = 0; i < n; i++) {
            // 计算 p[i] - (i+1)
            int diff = p[i] - (i + 1);
            // 检查是否存在匹配的宝石
            res += diffCount.getOrDefault(-diff, 0);
            // 更新哈希表
            diffCount.put(diff, diffCount.getOrDefault(diff, 0) + 1);
        }
        
        // 输出结果
        System.out.println(res);
    }
}
  • Cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int n;
    cin >> n;
    
    // 使用unordered_map来存储差值的出现次数
    unordered_map<int, int> diff_count;
    long long res = 0;
    
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        // 计算差值
        int diff = x - i;
        // 检查是否存在匹配的宝石
        res += diff_count[-diff];
        // 更新差值的出现次数
        diff_count[diff]++;
    }
    
    // 输出结果
    cout << res << "\n";
    
    return 0;
}

🍰 03.LYA的魔法调和

问题描述

LYA是一位魔法调和师,她有一组魔法元素,每个元素都有一个能量值。LYA希望将所有元素的能量值调和至1,这样它们就能完美融合。她可以使用一种特殊的调和魔法:每次选择两个不同的元素,然后同时将它们的能量值除以这两个数的任意一个公因数。

LYA想知道,她是否能通过若干次调和魔法,将所有元素的能量值都变为1。你能帮助她判断这是否可能吗?

输入格式

输入的第一行是一个整数 ),表示测试用例的数量。

对于每个测试用例:

  • 第一行包含一个整数 ),表示魔法元素的数量。
  • 第二行包含 个整数 ),表示每个魔法元素的初始能量值。

保证所有测试用例中 的总和不超过

输出格式

对于每个测试用例,如果LYA能够将所有元素的能量值调和为1,输出"YES",否则输出"NO"。

样例输入

2
3 
18 18 36
3
3 2 1

样例输出

YES
NO

样例解释

对于第一组测试数据:

  1. 将第一个和第三个元素同时除以6,得到{3, 18, 6}
  2. 将第二个和第三个元素同时除以6,得到{3, 3, 1}
  3. 将第一个和第二个元素同时除以3,得到{1, 1, 1}

对于第二组测试数据,无法通过调和魔法使所有元素变为1。

数据范围

  • 所有测试用例中 的总和不超过

题解

对于每个数,我们需要

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

学长刷题笔记 文章被收录于专栏

这里收集了超全的刷题笔记,欢迎大家的订阅,会持续跟新的

全部评论
改编是变难了还是简单了?
点赞 回复 分享
发布于 09-04 09:45 加拿大

相关推荐

点赞 评论 收藏
分享
1 5 评论
分享
牛客网
牛客企业服务