2018年校招全国统一模拟笔试(第一场)编程题参考题解

5月场正在报名,模拟考试赢内推,欢迎参加~


密码翻译

分析

根据题意实现就好了

时间复杂度

O(n)

参考代码

#include <bits/stdc++.h>

const int maxn = 100 + 5;

char s[maxn];
int main() {
    gets(s);
    int len = strlen(s);
    for(int i = 0; i < len; i++) {
        if('a' <= s[i] && s[i] <= 'y') s[i]++;
        else if('A' <= s[i] && s[i] <= 'Y') s[i]++;
        else if(s[i] == 'z') s[i] = 'a';
        else if(s[i] == 'Z') s[i] = 'A';
    }
    puts(s);
    return 0;
}

寻宝

分析

最小生成树,保留最大边即可。

时间复杂度

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct Node
{
    int p;
    int q;
    int k;    
}node;

vector<int> pre;
int unionsearch(int index) {
    while (pre[index] != index) {
        pre[index] = pre[pre[index]];
        index = pre[index];
    }
    return index;
}
void join(int x, int y) {
    if (pre[x] != pre[y]) {
        pre[x] = y;
    }
}
bool cmp(const node& vn1, const node & vn2) {
    return vn1.k < vn2.k;
}
int main(void) {
    int N, M;
    scanf("%d %d", &N, &M);
    vector<node> vn;
    for (int i = 0; i < M; i++) {
        node tmp;
        scanf("%d %d %d", &tmp.p, &tmp.q, &tmp.k);
        vn.push_back(tmp);
    }
    // initialize union set;
    for (int i = 0; i <= N; i++) {
        pre.push_back(i);
    }
    sort(vn.begin(), vn.end(), cmp);
    int res = 0;
    for (int i = 0; i < M; i++) {
        int rootA = unionsearch(vn[i].p);
        int rootB = unionsearch(vn[i].q);
        if (rootA != rootB) {
            if (res < vn[i].k) {
                res = vn[i].k;
            }
            join(rootA, rootB);
        }
    }
    cout << res << endl;
    return 0;
}

打车

分析

注意到n很小,直接枚举子集判断是否合法,在所有合法的方案中找size最大。

时间复杂度

O(n^2)

参考代码

#include <bits/stdc++.h>

using namespace std;

int n, s, p[15];
int main() {
    scanf("%d%d", &n, &s);
    for(int i = 0; i < n; i++) scanf("%d", &p[i]);
    int ans = 0;
    for (int x = 0; x < (1 << n); x++) {
        int mi = 10000000;
        int sum = 0;
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            if ((x & (1 << i)) != 0 ) {
                mi = min(mi, p[i]);
                sum += p[i];
                cnt++;
            }
        }
        if (sum >= s && sum - mi < s) {
            ans = max(ans, cnt);
        }
    }
    cout << ans << endl;

}

美丽的项链

分析

可以通过母函数求解。
比较直接的就直接用背包dp算就行了。

时间复杂度

O(nmr)

参考代码

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

long long f[2][105];

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    memset(f, 0, sizeof(f));
    f[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        memset(f[i & 1], 0, sizeof(f[i & 1]));
        int l, r;
        scanf("%d%d", &l, &r);
        for (int k = l; k <= r; k++)
            for (int j = m; j >= k; j--)
                f[i & 1][j] += f[i + 1 & 1][j - k];
    }
    printf("%lld\n", f[n & 1][m]);
    return 0;
}

排列

分析

如果某个数没有满足错排要求,直接和相邻的位置swap一下,统计次数即可。

时间复杂度

O(n)

参考代码

来源:牛客网

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

int a[maxn], n;
int main() {
    cin >> n;
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    int res = 0;
    for(int i = 0; i < n - 1; i++) {
        if(a[i] == i + 1) {
            swap(a[i], a[i + 1]);
            res++;
        }
    }
    if(a[n - 1] == n) res++;
    cout << res << endl;
    return 0;
}

勇敢的妞妞

分析

当k >= 5的时,每一维属性都取最大求和即可。
对于k < 5的时,预处理31种情况可能得到的最大的和。然后dfs枚举子集维护最大的答案即可。

时间复杂度

O(32 * 5 * n)

参考代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e4 + 5;

int mx[10];
int num[maxn][10];
int N, K;
int sta[32];
int dfs(int s, int cur) {
    if(cur == K) return 0;
    int tmp = 0;
    for(int i = s; i; i = (i - 1) & s) tmp = max(tmp, sta[i] + dfs(s ^ i, cur + 1));
    return tmp;
}
int main() {
    scanf("%d%d", &N, &K);
    memset(sta, 0, sizeof(sta));
    memset(mx, 0, sizeof(mx));
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < 5; j++) {
            scanf("%d", &num[i][j]);
            mx[j] = max(mx[j], num[i][j]);
        }
        for(int j = 0; j < 32; j++) {
            int res = 0;
            for(int k = 0; k < 5; k++) {
                if(j & (1 << k)) {
                    res += num[i][k];
                }
            }
            sta[j] = max(sta[j], res);
        }
    }
    if(K >= 5) {
        int ans = 0;
        for(int i = 0; i < 5; i++) ans += mx[i];
        printf("%d\n", ans);
    } else {
        printf("%d\n", dfs(31, 0));
    }
    return 0;
}
#校招#
全部评论
运**做了三道最简单的题 ↑_↑ 
点赞
送花
回复
分享
发布于 2018-03-16 10:01
果姐厉害了,表白♥
点赞
送花
回复
分享
发布于 2018-03-15 16:07
滴滴
校招火热招聘中
官网直投
顶果果!
点赞
送花
回复
分享
发布于 2018-03-15 16:18
为什么我的编程题就三道。。
点赞
送花
回复
分享
发布于 2018-03-15 23:07

相关推荐

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