【2022-09-13】百度秋招笔试五道编程题(A/B卷)

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经,目前已更新至美团、微软…
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

第一题:baidu型子串(A/B卷)

题目描述

小红拿到了一个字符串,她想知道有多少个"baidu"型子串?

所谓"baidu“型字符串,指第1个、第4个字母是辅音,第2、3、5个字符是元音,且每个字母都不相同的字符串。

例如,“taigu”、“huida”、“paobu”、"baoli"等都是"baidu"型字符串。

我们定义元音字母仅有’a、‘e’、‘i’、‘o’、'u’这五种,其余字母均为辅音字母。

输入描述

输入一个字符串,长度<=2e5

baiduxiaojiabankanjiaran

输出描述

输出"baidu"型子串的数量

2

解释:"baidu"和"duoxi"合法。其中"jiaba"和"jiara"不合法,因为a出现了2次。

思路

滑动窗口,维护一下窗口内字母特征以及字母出现次数即可。

代码

Python版本
import string

s = input()

if len(s) <= 4:
    print(0)
    exit(0)
else:
    cor = {v: i for i, v in enumerate(string.ascii_lowercase)}
    y = set(list('aeiou'))
    nums = [0 if i in y else 1 for i in s]
    ans = 0
    diff = 0
    count = [0] * 26
    cnt = 0
    for i in range(4):
        cnt = cnt * 10 + nums[i]
        count[cor[s[i]]] += 1
        if count[cor[s[i]]] > 1: diff += 1

    for i, v in enumerate(s[4:], start=4):
        cnt = cnt * 10 + nums[i]
        count[cor[v]] += 1
        if count[cor[v]] == 2:
            diff += 1

        if cnt == 10010 and not diff:
            ans += 1

        cnt -= nums[i - 4] * 10000
        count[cor[s[i - 4]]] -= 1
        if count[cor[s[i - 4]]] == 1:
            diff -= 1
    print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>

using namespace std;
bool isVow(char c) {
    switch(c) {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
        return true;
    }
    return false;
}
int main() {
    string s; cin >> s;
    const int n = s.length();

    int ans = 0;
    for (int i = 0; i < n-4; i++) {
        bool allDifferent = true;
        for (int j = i; j <= i+4; j++) {
            for (int k = j+1; k <= i+4; k++) {
                if (s[j] == s[k]) {
                    allDifferent = false;
                    break;
                }
            }
            if (!allDifferent) break;
        }
        if (allDifferent)
            ans += !isVow(s[i]) && isVow(s[i+1]) && isVow(s[i+2]) && !isVow(s[i+3]) && isVow(s[i+4]);
    }
    cout << ans << endl;
    return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递

第二题:01串(A卷)

题目描述

给定一个t,表示接下来有t行数据

给定一个01字符串s,对于每两个连续的子串,你可以把他们变成相反的子串

如 ”01“ 变成”10“ ,“00”变成”11“

如果能把s转换成所有字符相同的字符串,输出”Yes“;否则输出”No”

数据范围 len(s)<2e6

思路

贪心。任意相邻的偶数个0或1,我们可以直接将其反转。而对于奇数个,我们可以反转到只剩下1个0或1。那么最终就只剩下形如 …1…1…1…( ’.'为任意个0)或者…0…0…0…0… ( ’.'为任意个1) 的串。

因为我们只能反转相邻的两个字符,所以我们要把这些1或者0变换到相邻的位置。假设两个1中间有n个0,即100…001,那么我们可以将最右边的两个字符反转,得到100…010,此时两个1中间有n-1个0,相当于把最右边的1往左移了一位。在经过n次反转移位之后,可以得到1100…00,再反转一次就得到全为0的串。(两个0中间有n个1的情况类似)。

这说明了能够成功变换与字符0和字符1的位置无关,只与它们的数量有关。即如果给定串***有偶数个0,我们最终可以变换成全为1的串;如果有偶数个1,我们最终可以变换成全为0的串。

代码

CPP版本
#include <iostream>

using namespace std;

bool ac(string &s) {
    int cnt = 0;
    for (char c : s) {
        cnt += c == '1';
    }
    return !(cnt&1) || !((s.length()-cnt)&1);
}
int main() {
    int q; cin >> q;
    while (q--) {
        string s;
        cin >> s;
        cout << (ac(s) ? "Yes" : "No") << endl;
    }
    return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
def f(s, c):
    n = len(s)
    for i in range(n - 1):
        if s[i] != c:
            s[i + 1] = c if s[i + 1] != c else s[i]
            s[i] = c
    return s[-1] == c

t = int(input())
for _ in range(t):
    s = list(input().strip())
    if f(s, "0") or f(s, "1"):
        print("Yes")
    else:
        print("No")
# vx公众号关注TechGuide 实时题库 闪电速递

第三题:走矩阵(A卷)

题目描述

给定一个字符矩阵,矩阵仅由’r’,‘e’,'d’组成。

求从左上角到右下角的最少步数。可以从上下左右四个方向走,但是不能从’r’->‘d’, ‘e’->‘r’,‘d’->‘e’。

第一行输入n m (1<n,m<500)

n表示矩阵的行 m表示矩阵的列

接下来n行 输入一个长为m的”red”字符串

“red”字符串是指所有字符均为”r"或”e"或”d”

你可以在矩阵中上下左右移动

但是r不能移动到d e不能移动到r d不能移动到e

输出从左上角走到右下角最少需要多长时间

如无法到达输出-1

思路

类似最短路径问题 注意需要从终点走向起点

代码

Python版本
from collections import deque

ban = "rderde"
mp = {}
for i in range(0, 5, 2):
    mp[ban[i + 1]] = ban[i]
n, m = map(int, input().split())
board = []
for _ in range(n):
    s = list(input().strip())
    board.append(s)

inf = 10 ** 9

q = deque([(n - 1, m - 1)])
g = [[inf] * m for _ in range(n)]
g[n - 1][m - 1] = 0
while q:
    x, y = q.popleft()
    for dx, dy in [(0, -1), (0, 1), (1, 0), (-1, 0)]:
        nx, ny = dx + x, dy + y
        if (
            0 <= nx < n
            and 0 <= ny < m
            and mp[board[x][y]] != board[nx][ny]
            and g[nx][ny] == inf
        ):
            g[nx][ny] = g[x][y] + 1
            q.append((nx, ny))

if g[0][0] == inf:
    print(-1)
else:
    print(g[0][0])
# vx公众号关注TechGuide 实时题库 闪电速递
CPP版本
#include <bits/stdc++.h>

using namespace std;
int main() {
    int n, m; cin >> n >> m;
    vector<string> v(n);
    for (int i = 0; i < n; i++) cin >> v[i];
    if (n == 1 && m == 1) {
        cout << 0 << endl;
        return 0;
    }
    vector<vector<bool>> vis(n, vector<bool>(m));
    vis[0][0] = true;
    queue<pair<int, int>> q;
    q.emplace(0, 0);
    int step = 0;
    const int dx[]{-1, 0, 1, 0}, dy[]{0, -1, 0, 1};
    auto canGo = [] (char from, char to) -> bool {
        if (from == 'r' && to == 'd') return false;
        if (from == 'e' && to == 'r') return false;
        if (from == 'd' && to == 'e') return false;
        return true;
    };
    while (!q.empty()) {
        step ++;
        int sz = q.size();
        while (sz--) {
            auto p = q.front(); q.pop();
            int x = p.first, y = p.second;
            for (int i = 0; i < 4; i++) {
                int nx = x+dx[i], ny = y+dy[i];
                if (nx == n-1 && ny == m-1 && canGo(v[x][y], v[ny][ny])) {
                    cout << step << endl;
                    return 0;
                }
                if (nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && canGo(v[x][y], v[nx][ny])) {
                    vis[nx][ny] = true;
                    q.emplace(nx, ny);
                }
            }
        }
    }
    cout << -1 << endl;
    return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递

第四题:打怪物(B卷)

题目描述

有n个怪物排成一排,第i个怪物的血量为ai。小红有两个技能可以打怪:

  1. 强力攻击,消耗1mp,对一只怪物造成1点伤害。

  2. 踏前斩,消耗5mp,对当前怪物造成1的伤害,同时剑气将波及后两个怪物,对下一个怪物造成2点伤害,对下下个怪物造成3点伤害。

如果一个怪物受伤后血量小于等于0,则怪物死亡。死亡后怪物的尸体依然占据一个位置,会被踏前斩的剑气打到。

小红想知道,击杀全部怪物至少需要花费多少mp?

输入描述

输入一个n和n个数字作为所有怪物血量

5
1 2 4 2 3

输出描述

输出最小使用的mp

10

思路

贪心即可,因为5hp是可以消耗1+2+3=6滴血的。所以优先使用技能,剩下的普通攻击A掉。

贪心的时候注意从后往前遍历,这样可以通过100%,从前往后遍历只能通过0%。提供case:[1, 9, 8, 9, 8]:

  • 从前往后贪:[1,4,8,7,6]–>[0,2,5,7,6]–>[0,0,1,1,6]

    从后往前贪:[1,4,8,7,6]–>[1,4,6,3,0]–>[1,3,4,0,0]–>[0,1,1,0,0]

代码

Python版本
n = int(input())
a = list(map(int, input().split()))
ans = 0
i = 0
for i in range(n - 3, -1, -1):
    if a[i] >= 1 and a[i + 1] >= 2 and a[i + 2] >= 3:
        c = min(a[i], a[i + 1] // 2, a[i + 2] // 3)
        a[i] -= c
        a[i + 1] -= c * 2
        a[i + 2] -= c * 3
        ans += c * 5

print(ans + sum(a))
# vx公众号关注TechGuide 实时题库 闪电速递

第五题:for循环(B卷)

题目描述

小红拿到了一段java代码,请你判断其中最多有多少层for循环嵌套。

保证代码合法,且不含注释。循环语句只有for,条件语句只有if,循环语句和条件语句保证包含大括号用来控制范围。

代码中只有一个类和一个主函数。

输入描述

多行输入

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int a = 0 , b = 0;
        int n = in.nextInt();
        for (int i = 0; i < n; i++) {
            if ( a < b ) {
                a += b / 2;
            }
            for (int j = 0; j < n; j++) {
                b++;
                a += b;
            }
            for (int j = 1; j < n; j *= 2) {
                b--;
            }
        }
        System.out.println(a);
    }
}

输出描述

输出最大嵌套数

2

思路

模拟题,注意多行输入。维护一个栈维护遇到的大括号和过程值cnt=0,因为题目说了for循环必然使用大括号包裹,那么只需要判断栈入的大括号前面是不是for的大括号即可,如果是就cnt+1,否则就不管。每次遇到右括号就出栈,出栈的时候判断是不是for循环后的括号,如果是就cnt-1,否则就不管。遍历过程中最大的cnt就是结果。

代码

Python版本
import sys

lines = list(sys.stdin.readlines())
a = ''.join(lines)
stack = []
n = len(a)
ans = 0
cnt = 0

pf = 0  # 前一个是不是for
i = 0
while i < n - 4:
    if a[i] == '{':
        stack.append(pf)
        cnt += pf
        pf = 0
        i += 1
    elif a[i] == 'f' and a[i + 1] == 'o' and a[i + 2] == 'r':
        pf = 1
        i += 3
    elif a[i] == '}':
        cnt -= stack.pop()
        i += 1
    else:
        i += 1

    ans = max(ans, cnt)

print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2023年3月11日,美团春季招聘笔试中共包含五道编程题目。以下是对每道题目的简要说明: 1. 题目一:这道题目要求解决一个数字统计的问题。可能涉及到的知识点包括数据结构、循环和条件判断等。解决问题的思路可能是使用字典等数据结构来保存统计结果,并使用循环逐个读取输入数据并进行统计。 2. 题目二:这道题目可能是一个字符串处理的问题。需要使用字符串的方法进行操作,如提取、拼接、查找和替换等。可能的解决思路包括使用正则表达式、切片和遍历等。 3. 题目三:这道题目可能涉及到算法和数据结构的知识。可能是一道涉及到数组、链表、树等数据结构的问题。解决思路可能包括遍历、递归、搜索和排序等。 4. 题目四:这道题目可能是一个动态规划的问题。需要根据给定的条件和规则,通过动态规划的方式求解问题。解决思路包括定义状态和转移方程,使用递推或记忆化搜索进行求解。 5. 题目五:这道题目可能是一个图论或网络问题。需要根据给定的图或网络结构,解决一个相关的问题。可能涉及到广度优先搜索、深度优先搜索、最短路径等知识。解决思路可能包括使用图或网络的相关算法进行求解。 以上只是对这五道编程题目的一些可能情况进行的简要描述,具体的题目内容可能会有所不同。希望这些信息能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值