IT校招全国统一模拟笔试(秋招备战专场) 编程题参考代码汇总

题目https://www.nowcoder.com/test/5217106/summary     


变换次数

分析

暴力计算即可.

参考code

#include <bits/stdc++.h>

using namespace std;

int n, ans, tmp;
int main() {
    cin >> n;
    while(n > 9) {
        tmp = 1;
        for(; n; n /= 10) tmp *= n % 10;
        n = tmp;
        ans++;
    }
    cout << ans << endl;
}

神奇数

分析

枚举区间内的数,然后check一下要求的性质即可。

参考code

#include <bits/stdc++.h>

using namespace std;

bool isprime(int x) {
    for(int i = 2; i * i <= x; i++) {
        if(x % i == 0) return false;
    }
    return true;
}
bool check(int x) {
    int cnt[10];
    memset(cnt, 0, sizeof(cnt));
    while(x) {
        cnt[x % 10]++;
        x /= 10;
    }
    for(int i = 1; i < 10; i++) {
        for(int j = 1; j < 10; j++) {
            if(i != j && cnt[i] && cnt[j]) {
                if(isprime(i * 10 + j)) return true;
            }else if(i == j && cnt[i] >= 2) {
                if(isprime(i * 10 + j)) return true;
            }
        }
    }
    return false;
}
int main() {
    int a, b, ans = 0;;
    cin >> a >> b;
    for(int i = a; i <= b; i++) {
        if(check(i)) ans++;
    }
    cout << ans << endl;
    return 0;
}

添加字符

分析

分为A长度小于B的情况和等于的情况。
小于就枚举B串的一个偏移量,然后枚举维护最小的不相等的位数。
等于就直接对比就好了。

参考code

#include <bits/stdc++.h>

using namespace std;

int main() {
    string a, b;
    cin >> a >> b;
    int la = a.size(), lb = b.size();
    if(la < lb) {
        int ans = 1e9;
        for(int i = 0; i + la <= lb; i++) {
            int cnt = 0;
            for(int j = 0; j < la; j++) {
                if(a[j] != b[i + j]) cnt++;
            }
            if(cnt < ans) {
                ans = cnt;
            }
        }
        cout << ans << endl;
        return 0;
    } else {
        int cnt = 0;
        for(int j = 0; j < la; j++) {
            if(a[j] != b[j]) ++cnt;
        }
        cout << cnt << endl;
    }
    return 0;
}

数组变换

分析

对于每个数一直除2,然后最后check是否相等即可。

参考code

#include <bits/stdc++.h>

using namespace std;

int a[55];
int main() {
    int n;
    cin >> n;
    for(int i = 0; i < n; i++) cin >> a[i];
    string res = "YES";
    for(int i = 0; i < n; i++) {
        while(!(a[i] & 1)) a[i] >>= 1;
    }
    for(int i = 1; i < n; i++) {
        if(a[i] != a[0]) res = "NO";
    }
    cout << res << endl;
}

排序子序列

分析

考虑序列A_1, A_2, . . . , A_i是一个单调的序列.显然如果对于j < i把序列分为A_1, A_2. . . A_j 和 A_j+1, A_j+2, . . . , A_i 两个部分不会使问题变得更优.

于是我们可以贪心的去重复下面过程:
1、 从序列中找出最长的单调连续子序列
2、 删除找出的最长的单调连续子序列

这里的单调序列包括非递增和非递减,而判断子序列是否单调的时候,注意处理等于的情况。

参考code

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector <int> A;
    int ans = 1;
    for(int i = 0; i < n; ++i) {
        int x;
        cin >> x;
        if(A.size() <= 1)
            A.push_back(x);
        else {
            if(A[0] <= A.back() && A.back() <= x)
                A.push_back(x);
            else if(A[0] >= A.back() && A.back() >= x)
                A.push_back(x);
            else {
                ans++;
                A.clear();
                A.push_back(x);
            }
        }
    }
    cout << ans << endl;
    return 0;
}

组队竞赛

分析

对于所有参赛队员,我们把他们的水平值进行逆序排序,然后逐一挨着安排每个队伍,然后计算出队伍水平值总和,即为所求。对于a1 >= a_2 >= a_3... >= a{3N}, 我们可以容易观察出答案就是a2 + a_4 + a_6 +...+ a{2N}

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 300100;

int a[maxn];

int main() {
    int n; scanf("%d", &n);
    for(int i = 0; i < 3 * n; i++) scanf("%d", &a[i]);
    sort(a, a + 3 * n);
    long long ans = 0;
    for(int i = 0; i < n; i++) ans += a[n + 2 * i];
    printf("%lld\n", ans);
    return 0;
}

训练部队

分析

可以考虑把新兵分为两种类型。
一种战斗型(战斗值大于潜力值的),一种潜力型(相当于打了他可以获得潜力值),对潜力型的新兵进行战斗力值排序。
然后一种情况是潜力型中战斗值最高的牛牛去打完剩余的潜力型,因为战斗力值会越大越多,另一种情况考虑打完所有潜力型获得值是固定的,那么在攻击型中找一个能打完所有的潜力型的牛牛,并且战斗力值和潜力值要最大。
实现就是用的前缀和和二分

参考code

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int maxn = 100005;
int n;
int goodn,badn;
LL sum[maxn],MAX[maxn];
struct Node {
    LL x,y;
    Node() {}
    Node (const LL &_x,const LL &_y) { x=_x; y=_y; }
    bool operator < (const Node &t) const {
        if(x ^ t.x) return x < t.x;
        return y < t.y;
    }
}good[maxn],bad[maxn];
int search(int L, int R, LL x) {
    while(L < R) {
        int mid = (L + R + 1) >> 1;
        if(MAX[mid] < x) L = mid;
        else R = mid - 1;
    }
    return L;
}
LL solve() {
    LL ans = 0;
    ans = max(ans, sum[search(0, goodn - 1, good[goodn].x)] + good[goodn].x + good[goodn].y);
    for(int i = 1; i <= badn; i++) {
        int pos = search(0, goodn, bad[i].x);
        ans = max(ans, sum[pos] + bad[i].x + bad[i].y);
    }
    return ans;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        LL x, y;
        scanf("%lld%lld",&x, &y);
        if(x < y) good[++goodn] = Node(x,y);
        else bad[++badn] = Node(x,y);
    }
    sort(good + 1, good + goodn + 1);
    MAX[0] = 0; sum[0] = 0;
    for(int i = 1; i <= goodn; i++) {
        sum[i] = sum[i-1] + good[i].y - good[i].x;
        MAX[i] = max(MAX[i-1], good[i].x - sum[i-1]);
    }
    LL ans = solve();
    printf("%lld\n", ans);
    return 0;
}

牛牛的数列

分析

正着枚举记录一下当前位置的连续上升子序列长度,倒着也做一遍。
最后枚举一个连接点即可。

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000 + 5;
const int INF = 0x3f3f3f3f;

int a[maxn], n;
int pre[maxn], suf[maxn];
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", a + i);
    a[0] = INF, a[n + 1] = INF;
    for(int i = 1; i <= n; i++) pre[i] = a[i - 1] < a[i] ? pre[i - 1] + 1 : 1;
    for(int i = n; i >= 1; i--) suf[i] = a[i] < a[i + 1] ? suf[i + 1] + 1 : 1;
    int ans = 1;
    for(int i = 1; i <= n; i++) {
        ans = max(ans, pre[i - 1] + 1);
        ans = max(ans, suf[i + 1] + 1);
        if(a[i + 1] - a[i - 1] >= 2) ans = max(ans, pre[i - 1] + suf[i + 1] + 1);
    }
    printf("%d\n", ans);
    return 0;
}
#Java工程师##C++工程师##iOS工程师##安卓工程师##运维工程师##前端工程师##算法工程师#
全部评论
组队竞赛题目,如果数据 为1 2 3 4 5 6,按照给的解法分队为{1,2,3},{4,5,6}和为7。可是如果按照{1,5,6},{2,3,4}这样和是8。是不是就是反例了?
点赞 回复
分享
发布于 2017-05-19 23:41
训练新兵那道题,是否想的太简单了。 考虑如下测试用例:          战斗力   潜力 A     10          5 B     12          20 C     15          30 假设A先与B战斗,B的新的数据如下: B      7           20 然后B与C战斗,C的新的数据如下: C     28         30 最后得出的C的总值为58 而上面的代码最后跑出来的答案是53  
点赞 回复
分享
发布于 2017-05-20 10:03
阅文集团
校招火热招聘中
官网直投
大数据三个题目的java代码,数组变换,排序子序列,牛牛的数列三题。 其中排序子序列提供了我的动态规划解法。 https://github.com/XingxingHuang/Code_Practice/tree/master/nowcoder/nowcode_0519_test 另外上面 “数组变换” 一题中参考答案似乎没考虑数组中有值为0的情况,这种情况下会产生死循环
点赞 回复
分享
发布于 2017-05-21 01:40
训练部队为什么不考虑间接对战的情况呀,就是a和b打,b和c打,c胜利。这样就算a的潜力-战斗力是负数,c也可以有正的增量
点赞 回复
分享
发布于 2017-05-20 09:22
顶果姐!
点赞 回复
分享
发布于 2017-05-19 21:01
感谢大家的参与!只有多实战练习,才能发现不足,更好进步!期待下个月的模拟考~
点赞 回复
分享
发布于 2017-05-19 21:05
我说怎么通过只有60%,两道题都是60%,原来是结果超出了。。。居然没有想到改成long long
点赞 回复
分享
发布于 2017-05-19 21:08
新出的JavaScript(V8)是有bug吧。无论怎么写都是内部错误。换成Nodev0.12就100%了
点赞 回复
分享
发布于 2017-05-19 21:10
没有一个全过的,桑心
点赞 回复
分享
发布于 2017-05-19 21:10
如果我没看错题目的话。 组队竞赛 这个题目,好像是将3n个人分成n组,每组的能力值为,3个人的中间值? 那么你给出的这个解法,对于1,1,1,6,6,6,7,7,7. 这个就会得到1+6+7的结果。实际上应该是6+6+6才是最大的。 感觉这题得动规啊。(然而判我只过20%了。。) 如果是我看错题目了。。谁把正确的题目回复我一下。。。
点赞 回复
分享
发布于 2017-05-19 21:11
组队比赛题目。排序算法自己写了个冒泡去排序,结果时间复杂度过大。。。。
点赞 回复
分享
发布于 2017-05-19 21:12
题目描述能贴出来吗 忘了题目了 囧
点赞 回复
分享
发布于 2017-05-19 21:17
组队竞赛想成dp了,想了半天也不知道怎么优化效率,跪在这第二道题上了,╮(╯▽╰)╭
点赞 回复
分享
发布于 2017-05-19 21:30
对于a 1 >= a_2 >= a_3... >= a {3N}, 我们可以容易观察出答案就是a 2 + a_4 + a_6 +...+ a {2N}。我是看了答案还要想半天的笨蛋
点赞 回复
分享
发布于 2017-05-19 21:41
因为longlong只a了2.6的人是不是只有我一个。。。。。。
点赞 回复
分享
发布于 2017-05-19 21:53
训练部队 这道题能不能说一下MAX数组是干嘛的,以及二分搜索和solve函数是在干嘛啊...看不懂代码啊
点赞 回复
分享
发布于 2017-05-19 21:55
没通过全部的case能得分吗?求解答
点赞 回复
分享
发布于 2017-05-19 22:01
请问这个考得好能有什么好处?
点赞 回复
分享
发布于 2017-05-20 00:21
一道题都没有过,看来还是要多加练习才行啊
点赞 回复
分享
发布于 2017-05-26 01:11

相关推荐

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