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

膨胀的牛牛

分析

根据题意遇到跟当前大小一样的草料大小翻倍即可。

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 200 + 5;

int a[maxn], n, A;
int main() {
    scanf("%d%d", &n, &A);
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    for(int i = 0; i < n; i++) {
        if(a[i] == A) A += A;
    }
    printf("%d\n", A);
    return 0;
}

黑化的牛牛

分析

一个做法是枚举去除掉的字符然后去重一下。
其实我们仔细观察对于相邻的两个字符如果一样去除掉后一个是不会产生新的字符串的,于是问题就转化为计算字符串当前字符是否和前面字符相同,特殊处理下长度等于1的情况即可。

参考code

#include <bits/stdc++.h>

using namespace std;

string s;
int main() {
    cin >> s;
    int ans = 0;
    for(int i = 1; i < s.size(); i++) {
        if(s[i] != s[i - 1]) ans++;
    }
    if(s.size() == 1) ans = 0;
    ans++;
    cout << ans << endl;
    return 0;
}

黑白卡片

分析

考虑最终的状态只有两种,然后分别比较之后取最小值即可。

参考code

#include <bits/stdc++.h>

using namespace std;

string s;
int main() {
    cin >> s;
    int cnt1 = 0, cnt2 = 0;
    for(int i = 0; i < s.size(); i++) {
        if(i % 2 == 0) {
            if(s[i] != 'W') cnt1++;
        } else {
            if(s[i] != 'B') cnt1++;
        }
    }
    for(int i = 0; i < s.size(); i++) {
        if(i % 2 == 0) {
            if(s[i] != 'B') cnt2++;
        } else {
            if(s[i] != 'W') cnt2++;
        }
    }
    cout << min(cnt1, cnt2) << endl;
    return 0;
}

序列交换

分析

用vector存序列,枚举交换之后丢进set去重得到个数即可。

参考code

#include <bits/stdc++.h>

using namespace std;

int n;
set<vector <int> > s;
vector<int> x;
int main() {
    cin >> n;
    for(int i = 0; i < n; i++) {
        int tmp;
        cin >> tmp;
        x.push_back(tmp);
    }
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if(i != j) {
                swap(x[i], x[j]);
                s.insert(x);
                swap(x[i], x[j]);
            }
        }
    }
    cout << s.size() << endl;
    return 0;
}

丑陋的字符串

分析

前缀都是'?'部分都是有方案可以抵消掉的。。后面的部分遇到'?'考虑前一个是什么贪心放就好了。

参考code

#include <bits/stdc++.h>

using namespace std;

string str;
int calc(string s, int j) {
    int res = 0;
    for(int i = j + 1; i < s.size(); i++) {
        if(s[i] == s[i - 1]) res++;
    }
    return res;
}
int main() {
    cin >> str;
    int pos = 0;
    while(pos < str.size() && str[pos] == '?') pos++;
    for(int i = pos + 1; i < str.size(); i++) {
        if(str[i] == '?') {
            if(str[i - 1] == 'A') str[i] = 'B';
            else str[i] = 'A';
        }
    }
    cout << calc(str, pos) << endl;
    return 0;
}

庆祝61

分析

枚举排列来计算肯定是不可行的。。
考虑我们已经将身高升序排序了,然后对于前k个小朋友组成队形的身高差的最大值的最小值为f(k),并且第k个和第(k-1)个小朋友是相邻的。现在我们加入第(k+1)个小朋友,考虑到第(k + 1)个小朋友身高是大于等于前面的小朋友,插入队形之后,第(k + 1)个小朋友一定与两个小朋友相邻, 所以当我们将第(k + 1)个小朋友插入到第k个和第(k - 1)个小朋友中间可以得到f(k + 1)的下界一定是max(f(k), h[k] - k[k - 2]),我们又注意到这样插入之后第(k + 1)个和第k个小朋友还是相邻的,于是这样可以一直推广下去。考虑最初3个小朋友的时候这样也是可行的, 于是问题变成了求max(h[i] - h[i - 2])。可以写出很简洁的代码。

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 20 + 5;

int n;
int h[maxn];
int main() {
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &h[i]);
    sort(h, h + n);
    int ans = 0;
    for(int i = 2; i < n; i++) ans = max(ans, h[i] - h[i - 2]);
    cout << ans << endl;
}

随机的机器人

分析

考虑dp[i % 2][j][k]表示走了i步之后恰好有j个红色格子,并且此时机器人正好站在第k个红色格子上的概率。最后求一个可能的状态的带权和就是所求期望。时间复杂度O(n ^ 3)

这个题应该还有很多做法,甚至可以做到O(n^2),O(n),欢迎讨论.

参考code

#include <bits/stdc++.h>

using namespace std;

const int maxn = 500 + 5;

double dp[2][maxn][maxn];
int n ;
int main() {
    cin >> n;
    double ans = 0;
    dp[0][1][0] = 1.0;
    for(int i = 1; i <= n; i++) {
        int cur = i % 2, old = 1 - (i % 2);
        for(int j = 1; j <= i + 1; j++) for(int k = 0; k < j; k++) dp[cur][j][k] = 0;
        for(int j = 1; j <= i; j++) for(int k = 0; k < j; k++) {
            if(dp[old][j][k] > 0) {
                int pos1 = j, pos2 = k + 1;
                if(pos1 == pos2) ++pos1;
                dp[cur][pos1][pos2] += 0.5 * dp[old][j][k];
                int pos3 = j, pos4 = k - 1;
                if(pos4 == -1) {pos3++,pos4++;}
                dp[cur][pos3][pos4] += 0.5 * dp[old][j][k];
            }
        }
    }
    for(int i = 1; i <= n + 1; i++) {
        for(int j = 0; j < i; j++) {
            ans += i * dp[n % 2][i][j];
        }
    }
    printf("%.1f\n", ans);
    return 0;
}

逃离农场

分析

考虑dp[i][k][sum]表示前i个奶牛中选取k个他们的编号和为sum的方案数,于是有:
dp[i][k][sum] = dp[i - 1][k][sum] + dp[i - 1][k - 1][(sum - i + n) % n]
然后可以滚动优化或者压缩一维空间。

参考code

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;
int n, k;
int dp[55][1005];
int main() {
    cin >> n >> k;
    dp[0][0] = 1;
    for(int i = 0; i < n; i++) {
        for(int j = k; j >= 1; j--) {
            for(int x = 0; x < n; x++) {
                dp[j][x] = (dp[j][x] + dp[j - 1][x - i < 0 ? x - i + n : x - i]) % mod;
            }
        }
    }
    cout << dp[k][0] << endl;
    return 0;
}
#Java工程师##C++工程师##iOS工程师##安卓工程师##运维工程师##前端工程师##算法工程师#
全部评论
哎  太扎心了
点赞 回复
分享
发布于 2017-06-16 21:10
dp 不到三维都不算题了吗。。
点赞 回复
分享
发布于 2017-06-16 21:12
博乐游戏
校招火热招聘中
官网直投
沙发
点赞 回复
分享
发布于 2017-06-16 21:01
感觉牛客的后台好**,碰到好几次本地可以过好多测试点,结果提交之后一个也过不了的情况。贼气,希望以后校招笔试尽量少碰到在牛客的笔试
点赞 回复
分享
发布于 2017-06-16 21:05
c++最高水到2.3,有待进步.....
点赞 回复
分享
发布于 2017-06-16 21:13
学习了,那两道好难
点赞 回复
分享
发布于 2017-06-16 21:01
感觉C++的有点难
点赞 回复
分享
发布于 2017-06-16 21:02
+1
点赞 回复
分享
发布于 2017-06-16 21:03
这次的编程题只AC了一道,被虐哭
点赞 回复
分享
发布于 2017-06-16 21:03
AC了一题,后面两个,一个随机机器人,一个逃离农场,随机机器人想了好久放弃了,逃离农场没有去重复,哎,心累
点赞 回复
分享
发布于 2017-06-16 21:04
大数据方向的三道编程,只通过了第一道的20%测试用例.....真心觉得好难
点赞 回复
分享
发布于 2017-06-16 21:04
求测试数据~~
点赞 回复
分享
发布于 2017-06-16 21:05
谢谢,有代码就可以跟着学习一波了~~
点赞 回复
分享
发布于 2017-06-16 21:05
我觉得第一题我代码有问题还是ac了。。。
点赞 回复
分享
发布于 2017-06-16 21:06
好难啊。。。
点赞 回复
分享
发布于 2017-06-16 21:10
六一那个一直没有思路~感谢分享
点赞 回复
分享
发布于 2017-06-16 21:11
只能做个61 看来我真是该去庆祝下61了
点赞 回复
分享
发布于 2017-06-16 21:14
C++第二题有点难啊,三维dp。。我用回溯就知道不行(▼皿▼#)
点赞 回复
分享
发布于 2017-06-16 21:16
后面两道都是三维dp,真是好难
点赞 回复
分享
发布于 2017-06-16 21:16
这次题目偏难了。。。
点赞 回复
分享
发布于 2017-06-16 21:18

相关推荐

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