首页 > 【题解】牛客模考 · 2021年第一次校招模拟笔试

【题解】牛客模考 · 2021年第一次校招模拟笔试

天弃之子

题意

游戏共有 关,每一关有 个按钮,其中只有一个可以过关,选择错误就会重新开始

玩家可以通过试错记住正确的按钮

问玩家运气最差时(每一关都要试 次才过关)共需要按多少次按钮才能通关。


分析

这道题最重要的环节就是读懂题目

从题意中分析出【每一关都要试 次】之后就比较容易了


对于每一关来说,都要进行 次失败

每次失败要先通过前面的 关,再算上当前这关,需要按 次按钮

所以往答案里累加

再算上最终成功的那次,通过 关需要按 次按钮即可


C++ 代码

long long findMaxButtons(vector<int>& a) {
    long long res = a.size();
    for(int i = 0; i < a.size(); i ++) {
        //  第i关要失败a[i] - 1次,每次都要按i次按钮,每次都要按i次按钮,共(a[i] - 1) * i次
        res += (long long)(a[i] - 1) * (i + 1);
    }
    return res;
}

Java 代码

public long findMaxButtons (int[] a) {
    long res = a.length;
    for(int i = 0; i < a.length; i ++) {
        //  第i关要失败a[i] - 1次,每次都要按i次按钮,每次都要按i次按钮,共(a[i] - 1) * i次
        res += (long)(a[i] - 1) * (i + 1);
    }
    return res;
}

Python 代码

def findMaxButtons(self , a ):
    n = len(a)
    res = n
    for i in range(0, n):
        # 第i关要失败a[i] - 1次,每次都要按i次按钮,每次都要按i次按钮,共(a[i] - 1) * i次
        res += (a[i] - 1) * (i + 1)
        return res

刷墙

题意

一个长度为 串,要把串变成某个位置左边全是 ,右边全是 至少要修改几个字符


分析

我们不知道应该把串变成几个 几个 ,考虑枚举 的分界点

设串的下标为 ,枚举的分界点为 ,令 全部为 全部为

这个区间内的数全变成 的次数等于这个区间内 的个数

这个区间内的数全变成 的次数等于这个区间 的个数

可以预处理前缀和 的个数,然后就可以在 的时间复杂度内求出每个分界点要变化的数的个数,更新答案即可


C++ 代码

#include<cstdio>
#include<algorithm>

using namespace std;

const int N = 100010;

char s[N];
int sum[N];

int main()
{
    int n;
    scanf("%d%s", &n, s + 1);

    for(int i = 1; i <= n; i ++)
        sum[i] = sum[i - 1] + s[i] - '0';

    int res = n;
    for(int i = 0; i <= n; i ++)
    {
        //  [1, i]中'0'的个数为 i - sum[i]
        //  [i + 1, n]中'1'的个数为 sum[n] - sum[i]
        res = min(res, i - sum[i] + sum[n] - sum[i]);
    }
    printf("%d\n", res);
    return 0;
}

Java 代码

import java.util.Scanner;

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

        String s = ' ' + sc.next();

        int[] sum = new int[n + 1];
        for(int i = 1; i <= n; i ++) {
            sum[i] = sum[i - 1] + s.charAt(i) - '0';
        }

        int res = n;
        for(int i = 0; i <= n; i ++)
        {
            //  [1, i]中'0'的个数为 i - sum[i]
               //  [i + 1, n]中'1'的个数为 sum[n] - sum[i]
            res = Math.min(res, i - sum[i] + sum[n] - sum[i]);
        }
        System.out.println(res);
    }
}

Python 代码

n = int(raw_input())
s = ' ' + raw_input()

sum = [0] * (n + 1)
for i in range(1, n + 1):
    sum[i] = sum[i - 1] + int(s[i])

res = n
for i in range(0, n + 1):
    # [1, i]中'0'的个数为 i - sum[i]
    # [i + 1, n]中'1'的个数为 sum[n] - sum[i]
    res = min(res, i - sum[i] + sum[n] - sum[i])
print res

胜者为王

题意

三个人各自拥有一个字符串,他们的字符串长度相等,游戏进行 回合,每回合每个人必须修改自己字符串中的一个字母,每个人最终得分是他字符串中出现次数最多的字母数量,判断谁最终得分最多。


分析

有一个显而易见的贪心策略是先找到出现最多的字母是哪个,然后把其他字母尽可能都改成这个字母

设出现次数最多的字母数量是 ,再进行 回合,这个字母就可以有

如果 不必担心在全部改成同一个字母之后每回合还必须改掉一个

可以留一个字母先改成其他字母,在最后一回合再改成目标字母即可


C++ 代码

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010;

char a[N], b[N], c[N];
int cnt[256];

int main()
{
    int n;
    scanf("%d%s%s%s", &n, a, b, c);

    int x = 0, y = 0, z = 0;
    for(int i = 0; a[i]; i ++)  x = max(x, ++ cnt[a[i]]);
    memset(cnt, 0, sizeof cnt);
    for(int i = 0; b[i]; i ++)  y = max(y, ++ cnt[b[i]]);
    memset(cnt, 0, sizeof cnt);
    for(int i = 0; c[i]; i ++)  z = max(z, ++ cnt[c[i]]);

    int len = strlen(a);
    x = min(x + n, len);
    y = min(y + n, len);
    z = min(z + n, len);

    if(x > y and x > z)  puts("xiaoming");
    else if(y > x and y > z)  puts("xiaowang");
    else if(z > x and z > y)  puts("xiaoli");
    else  puts("draw");
    return 0;
}

Java 代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String a = sc.next();
        String b = sc.next();
        String c = sc.next();

        int[] cnt = new int[256];
        int x = 0, y = 0, z = 0;
        for(int i = 0; i < a.length(); i ++) {
            x = Math.max(x, ++ cnt[a.charAt(i)]);
        }
        for(int i = 0; i < cnt.length; i ++)  cnt[i] = 0;
        for(int i = 0; i < b.length(); i ++) {
            y = Math.max(y, ++ cnt[b.charAt(i)]);
        }
        for(int i = 0; i < cnt.length; i ++)  cnt[i] = 0;
        for(int i = 0; i < c.length(); i ++) {
            z = Math.max(z, ++ cnt[c.charAt(i)]);
        }
        int len = a.length();
        x = Math.min(x + n, len);
        y = Math.min(y + n, len);
        z = Math.min(z + n, len);
        if(x > y && x > z)  System.out.println("xiaoming");
        else if(y > x && y > z)  System.out.println("xiaowang");
        else if(z > x && z > y)  System.out.println("xiaoli");
        else  System.out.println("draw");
    }
}

Python 代码

n = int(raw_input())
a = raw_input()
b = raw_input()
c = raw_input()

x, y, z = 0, 0, 0
cnt = [0] * 256
for i in a:
    cnt[ord(i)] += 1
    x = max(x, cnt[ord(i)])

cnt = [0] * 256
for i in b:
    cnt[ord(i)] += 1
    y = max(y, cnt[ord(i)])

cnt = [0] * 256
for i in c:
    cnt[ord(i)] += 1
    z = max(z, cnt[ord(i)])

length = len(a);
x = min(x + n, length);
y = min(y + n, length);
z = min(z + n, length);

if x > y and x > z:
    print "xiaoming"
elif y > x and y > z:
    print "xiaowang"
elif z > x and z + y:
    print "xiaoli"
else:
    print "draw"

全部评论

(9) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期精华帖

热门推荐