网易2019校招笔试编程题参考代码

与更多牛友一起讨论笔试~
发本场网易笔试题解,赢取牛客T恤!
发题解,赢取卫衣~

代价

分析

升序排序相减即可。

时间复杂度

O(1)

参考代码

#include <bits/stdc++.h>

using namespace std;
int a[3];
int main() {
    int ans = 0;
    for(int i = 0; i < 3; i++) {
        scanf("%d", &a[i]);
    }
    sort(a, a + 3);
    for(int i = 2; i > 0; i--) {
        ans = ans + a[i] - a[i - 1];
    }
    printf("%d\n", ans);
    return 0;
}

访友

分析

贪心,除了最后一步,每一次都走5步,若还有剩下,再走一步即可。

时间复杂度

O(1)

参考代码

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

int main() {
    long long int n;
    cin >> n;
    cout << ceil((double)n / 5);
    return 0;
}

买房

分析

题目给定了房子数和已经入住的住户数量。
先考虑几个特例
n<=2,k<=1,n=k的情况下无法达成条件,故直接输出0 0
对于其它情况,显然最小的情况固定为0
对于k幢房子,在n足够大的情况下有k-1幢满足条件的房子(6 3时#-#-#-),即(2*k-1)<=n时
否则为n-k,(6 4时#-#-##)

时间复杂度

O(1)

参考代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, k, t;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &k);
        if(n <= 2 || k <= 1 || n == k) {
            printf("0 0\n");
            continue;
        }
        if((2 * k - 1) <= n) {
            printf("0 %d\n", k - 1);
        }
        else {
            printf("0 %d\n", n - k);
        }
    }
    return 0;
}

翻转翻转

分析

先考虑n = m = 1的情况,翻转一次,故输出1
我们令输入的n <= m
当n = 1,m > 1时,最边上两块会被翻转两次,中间的会被翻转三次,故输出(m - 2)
当2 <= n <= m时,四个角会被翻转四次,四边上除了角外的部分会被翻转六次,中间剩余的部分会被翻转九次,故输出(n - 2)(m - 2)

时间复杂度

O(1)

参考代码

#include <bits/stdc++.h>

using namespace std;
int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        long long n, m;
        scanf("%lld%lld", &n, &m);
        if(n > m) swap(n, m);
        if(n == 1 && m == 1){
            printf("1\n");
            continue;
        }
        if(n == 1){
            printf("%lld\n", m - 2);
            continue;
        }
        printf("%lld\n", (n - 2) * (m - 2));
    }
    return 0;
}

橡皮泥斑马

分析

可以发现,无论操作多少次,总是由两段下标连续的串组成,所以直接在原串后面接上原串,求最长黑白相间连续串即可。

时间复杂度

O(|S|),其中|S|表示字符串长度

参考代码

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

int main() {
    string s;
    cin >> s;
    s += s;
    int ans = 1;
    for (int i = 0; i < s.size(); i++) {
        int j = 1;
        while (i != s.size() - 1 && s[i] != s[i + 1]) {
            i++;
            j++;
        }
        ans = max(ans, j);
    }
    if (s.size() / 2 < ans) {
        ans = s.size() / 2;
    }
    printf("%d\n", ans);
    return 0;
}

社团******

分析

暴力枚举这个人需要多少人支持才能当选,每次枚举时,超出这个数量以及和这个数量相等的人一定需要被改变,之后数量不足,再从剩下的人中选择。

时间复杂度

O(m n logn)

参考代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3005;

vector<int> G[N];
int vis[N];
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    ll ans = 1e18;
    for (int i = 0;i < n;i++) {
        int p, c;
        scanf("%d%d", &p, &c);
        G[p].push_back(c);
        vis[p]++;    
    }
    int mx = 0;
    for (int i = 1;i <= m;i++) {
        if (vis[i] > mx) {
            mx = vis[i];
        }
    }
    int cnt = 0;
    for (int i = 1;i <= m;i++) {
        if (vis[i] == mx) cnt++;
    }
    if (cnt == 1 && vis[1] == mx) return 0*puts("0");
    for (int i = 1; i <= m; i++) sort(G[i].begin(), G[i].end());
    for (int i = n; i >= 1; i--) {
        vector<int> r;
        int num = i - vis[1];
        ll sum = 0;
        for (int j = 1; j <= m; j++) {
            if (vis[j] >= i && j != 1) {
                int tmp = vis[j] - i + 1;
                for (int k = 0; k < min(tmp, (int)G[j].size()); k++) {
                    r.push_back(G[j][k]);
                } 
            }
        }
        for (int j = 0; j < r.size(); j++) {
            num--;
            sum += r[j];
        }
        if (num <= 0) {
            ans = min(ans, sum);
            continue;
        }
        r.clear();
        for (int j = 1; j <= m; j++) {
            if (vis[j] >= i && j != 1) {
                int tmp = vis[j] - i + 1;
                if (tmp >= G[j].size()) continue;
                for (int k = tmp; k < G[j].size(); k++) {
                    r.push_back(G[j][k]);
                } 
            }
        }
        for (int j = 1; j <= m; j++) {
            if (vis[j] < i && j != 1) {
                for (int k = 0; k < G[j].size(); k++) {
                    r.push_back(G[j][k]);
                }
            }
        }
        sort(r.begin(), r.end());
        for (int j = 0;j < r.size();j++) {
            num--;
            sum += r[j];
            if (num <= 0) break;
        }
        if (num <= 0) ans = min(ans,sum);
    }
    cout << ans << endl;
    return 0;
}

香槟塔

分析

每层塔建立一个mark标记指向离他最近的未装满的层,执行2操作时对当前层的mark进行添加,如果加满移至下一个mark。使用并查集路径压缩的思想不断把mark下移。执行1操作时直接输出结果。

时间复杂度

O(m + n)

参考代码

#include <bits/stdc++.h>

const int MAXN =  200015;

using namespace std;

int mark[MAXN], a[MAXN], b[MAXN];

int _find(int x) {
    if(x == 0) return x;
    if(a[x] != b[x]) return x;
    return mark[x] = mark[x + 1] = _find(mark[x + 1]);

}
int main() {
    int n, m, x, y, d;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        b[i] = 0;
        mark[i] = i;
    }
    int op;
    while(m--) {
        scanf("%d", &op);
        if(op == 2) {
            scanf("%d%d", &x, &y);
            while(y) {
                x = _find(x);
                if(x == 0)break;
                d = min(a[x] - b[x], y);
                b[x] += d;
                y -= d;
            }
        }
        else {
            scanf("%d", &x);
            printf("%d\n", b[x]);
        }
    } 
    return 0;
}
#网易##校招#
全部评论
写题解,拿卫衣~https://www.nowcoder.com/discuss/96308?type=2&order=0&pos=4&page=2
点赞 回复 分享
发布于 2018-09-08 17:12
翻牌那题一样的代码,只过了80%,还有什么数据过不了?
点赞 回复 分享
发布于 2018-09-08 17:31
斑马那道题。。啥意思,为啥直接接原串
点赞 回复 分享
发布于 2018-09-08 17:13
黑白串那道题,可以把字符串首尾相连拼成一个环,求环中连续最长黑白相间的长度就可以了。
点赞 回复 分享
发布于 2018-09-08 20:51
解释一下斑马那道题,先读题,将串分割为两个子串后分别翻转,再将翻转后的子串拼接,这个拼接操作不允许调换原本两串的先后顺序(即a+b子串不允许拼接为b+a),题目没有描述清晰。  按照这个题意分析题中的一系列操作有什么性质: 举个栗子,现有串“12345”; 从3、4之间切,俩子串为“123”、“45”; 分别翻转,为“321”、“54”; 拼接,为“32154”; 这时候如果把整个串翻转一次(这步不是题目要求对,是为了更清晰地分析题中操作的性质),是不影响本题所求的最长连续相间串长的,翻转后结果为“45123”; 而“45123”是将原串“12345”做“123|45”分割后进行循环移位的结果:对串进行循环左移(或右移)使分割处‘|’位于串的起始(右移对应的是结束)位置,得到“|45123”; 由于进行一次循环移位的移动位数没有限制(位数由分割方式决定),多次循环移位操作的结果都可以由一次循环移位操作得到(可移0到(length(string)-1)位),因此只需分析一次循环移位操作即可——问题转化为寻找循环移位后串的最长连续相间串,于是自然地想到复制一份自身接到尾巴后,扫描一遍这个两倍串得到的答案即为所求。
点赞 回复 分享
发布于 2018-09-09 12:11
请收下我的膝盖,✺◟(∗❛ัᴗ❛ั∗)◞✺
点赞 回复 分享
发布于 2018-09-08 17:07
厉害了
点赞 回复 分享
发布于 2018-09-08 17:09
…这次的那个走几步的题真的是一句话ac😂
点赞 回复 分享
发布于 2018-09-08 17:14
香槟别的都写得没问题,mn写反没a出来,好气啊!
点赞 回复 分享
发布于 2018-09-08 17:15
斑马题可以详细解释一下吗?~可能我有点蠢😂
点赞 回复 分享
发布于 2018-09-08 17:15
厉害
点赞 回复 分享
发布于 2018-09-08 17:29
斑马的那个有问题,可以试一下wbbwwb这个用例,按题目意思应该是6
点赞 回复 分享
发布于 2018-09-08 17:30
js 做买房n ,k 的那道题一直格式错误,到最后都没出来,好难过。还影响后面的问答题了。
点赞 回复 分享
发布于 2018-09-08 17:38
香槟那个题,一个接收容量的数组vec,再开一个real数组,保存真实体积,初始化每个为0。 倒酒就从倒的这一层去看真实体积就好了。 while( v > 0 ) {   if( vec[x-1] - real[x-1] <= v ) {   v -= ( vec[x-1] - real[x-1] );       real[x-1] = vec[x-1];   x++; }   else {   real[x-1] += v; break; } }
点赞 回复 分享
发布于 2018-09-08 18:00
斑马莫非可以旋转n次,答案就是w次数等于b时为w+b,不等于时为2*min(w,b)+1?
点赞 回复 分享
发布于 2018-09-08 18:07
香槟塔你那样的思路复杂度应该是n+m吧
点赞 回复 分享
发布于 2018-09-08 18:59
赞同10#,感觉斑马题目的解答很明显是有问题的吧,题目意思是找一个子串翻转后重新拼接,求新串中的最大连续黑白相间的数量吧,难道是我题目理解错了??
点赞 回复 分享
发布于 2018-09-08 19:57
额,题目不一样。。
点赞 回复 分享
发布于 2018-09-08 21:25
。。。3道ac一道半,最后一个住房直接弃了
点赞 回复 分享
发布于 2018-09-08 21:59
翻牌那道题没读懂,有大佬给渣渣解释一下嘛
点赞 回复 分享
发布于 2018-09-09 14:52

相关推荐

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