校招全国统一模拟笔试(七月场)编程题参考代码

在线练习模考7月场编程题:https://www.nowcoder.com/test/11488280/summary

牛牛的游戏

分析

模拟,判断。

时间复杂度分析

O(1)

参考代码

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string a,b,c;
    cin >> a >> b >> c;
    if (*a.rbegin() == *b .begin() && *b.rbegin() == *c.begin()) puts("YES");
    else puts("NO");
    return 0;
}

艰难的抉择

分析

贪心。
由于第一种操作之后必须是整数,那么可以进行的条件是序列中至少存在一个数是2的倍数,于是每一次的操作中,对n-1个数乘3,对一个可以被2整除的数除以2。所以最多的次数就是每个数字分解出的2的幂的和。

时间复杂度分析

O(nlogx)

参考代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    scanf("%d", &n);
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        while (x % 2 == 0) {
            cnt++;
            x /= 2;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

数字比较

分析

取对数进行比较。

时间复杂度

O(1)

参考代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    int x, y;
    scanf("%d%d", &x, &y);
    if (x == y) puts("=");
    else {
        long double a = 1.0 * y * log2(x);
        long double b = 1.0 * x * log2(y);
        if (fabs(a-b) < 1e-15) puts("=");
        else if (a > b) puts(">");
        else puts("<");
    }
    return 0;
}

序列最小化

分析

贪心,枚举1的相对位置,把序列分割为前半段和后半段,每次最多替换k - 1个数字,前半段的次数加后半段的次数,每次更新答案。

时间复杂度

O(n)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;
int a[N];

int main() {
    int n, k;
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    if (k >= n) return puts("1") * 0;
    int ma = -1;
    for (int i = 1;i <= n;i++) {
        if (a[i] == 1) ma = i;
    }
    int ans = N;
    for (int i = 0;i < k;i++) {
        int cnt = 0;
        int pre = ma - i - 1;
        int sub = pre + k;
        sub = n - sub;
        if (pre > 0 && pre <= n)
        {
            cnt += pre / (k-1);
            if (pre % (k-1)) cnt++;
        }
        if (sub > 0)
        {
            cnt += sub / (k-1);
            if (sub % (k-1)) cnt++;
        }
        ans = min(cnt,ans);
    }
    printf("%d\n", ++ans);
    return 0;
}

括号匹配

分析

对于每个字符串,用栈判断是否合法,每次栈为空或者栈中只有一种类型的括号,那么就是合法的,否则不合法。
统计完后,用乘法原理累加即可。

时间复杂度

O(n*logn)

参考代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 3e5 + 10;

char s[N];
map<int,int> l;
map<int,int> r;
stack<char> S;
int main() {
    int n;
    scanf("%d", &n);
    int com = 0;
    for (int i = 0; i < n; i++) {
        scanf("%s", s);
        while (!S.empty()) S.pop();
        int sz = strlen(s);
        for (int i = 0;i < sz; i++) {
            if (s[i] == '(') {
                S.push(s[i]);
            }
            else {
                if (S.empty()) {
                    S.push(s[i]);
                }
                else
                {
                    if (S.top() == '(') S.pop();
                    else S.push(s[i]);
                }
            }
        }
        int ln = 0,rn = 0;
        if (S.empty()) {
            com++;
            continue;
        }
        while (!S.empty()) {
            char t = S.top();
            if (t == '(') ln++;
            else rn++;
            S.pop();
        }
        if (ln == 0) {
            r[rn]++;
        }
        else if (rn == 0) {
            l[ln]++;
        }
    }
    ll ans = (ll)com * com;
    for (auto it = l.begin();it != l.end();++it) {
        int tmp = it -> first;
        int num = it -> second;
        ans += 1LL * num * r[tmp];
    }
    printf("%lld\n", ans);
    return 0;
}
#校招#
全部评论
序列最小化,直接输出(n - k) / (k - 1) + 1即可ac,o(1)。会算卷积核的应该能看懂是啥意思吧。
点赞
送花
回复
分享
发布于 2018-07-20 10:57
序列最小化不需要判断 1 的位置。 作者:猪小戒o_O 链接:https://www.nowcoder.com/discuss/87215?type=0&order=0&pos=10&page=0 来源:牛客网 int solution(int n, int k) { int ans = 0 while (n > k) { n = n - k + 1; ++ans; } return ans + 1; }
点赞
送花
回复
分享
发布于 2018-07-19 22:04
滴滴
校招火热招聘中
官网直投
感觉序列化那道题出错了,不然太简单了,和输入序列完全无关。答案就是(n-1)/(k-1)向上取整。 我看错题目,以为可以有重复数字,结果特别复杂。
点赞
送花
回复
分享
发布于 2018-07-27 13:07
括号匹配没太看懂,可以麻烦解释一下吗,为什么只有一种类型括号也算合法
点赞
送花
回复
分享
发布于 2018-07-20 09:07
括号匹配的题目怎么理解啊
点赞
送花
回复
分享
发布于 2018-07-24 19:40
数字比较的题目为什么需要取对数?直接进行乘方的运算不行吗?
点赞
送花
回复
分享
发布于 2018-07-24 20:55
括号匹配根据题解思路是这样的,大致分三种情况: (1)根据每个输入一次统计,如果字符串本身就是符合的,也就是最后S为empty,则com自增,最后com*com即为本身就符合的字符串拼接的所有可能情况,比如说:A、B两个串符合,最后情况就有,AA、AB、BA、BB中情况; (2)对于像(()(这样的情况,中间的括号在运行过程中从栈中退出来,最后栈中只剩((,将这种情况通过map保存,l[ln]++,其中ln代表此时的左括号个数;对于后括号也是类似,存入r[rn]中;将所有输入的字符串的情况统计出来;最后将对应的l[1]r[1],r[2]r[2]...算出来依次相加;还是举个例子,比如说给定的字符串中,左括号为2的有:(()(,只有1种情况,而右括号为2的有:))、())),则最后能拼成的就有1*2中情况; (3)对于像)(这样的字符串,它既不是自身就符合括号匹配的串,也不是最后经过处理之后只剩一种括号的串,这种串没法和其他串拼接出符合要求的串,所以不统计;
点赞
送花
回复
分享
发布于 2018-07-25 13:55
学Java的表示看不懂   for(auto it = l.begin();it != l.end();++it) {         inttmp = it -> first;         intnum = it -> second;         ans += 1LL * num * r[tmp];     }
点赞
送花
回复
分享
发布于 2018-07-31 16:46
不太理解代码规范的要求是什么,代码规范竟然是0分
点赞
送花
回复
分享
发布于 2018-08-01 16:39

相关推荐

点赞 18 评论
分享
牛客网
牛客企业服务