网易2019实习生招聘编程题集合 题解

题目链接:https://www.nowcoder.com/test/9763997/summary

1.牛牛找工作:

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。

解题思路分析:

每个工作都有自己的难度和工资,我们需要求的是每一个人能承受的难度中工资最高的,首先分析能否能用一次排序就达到效果,如果把难度作为关键字排序的话,那么在排好序中的序列中,也不能直接得到答案,所以我们需要将排好序的序列中维护一个前缀数组,记录从前面到当前位置的最高工资,因为我们的序列是按难度排序的,所以排在前面的难度一定不会比后面的高,所以这个前缀数组是可维护的,接下来我们再通过二分查找找到每个人相应的难度位置,再通过查询前缀数组得到答案。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100000+5;
struct Node {
    int d, p;
}node[maxn];
int Max[maxn];
int cmp(Node a, Node b) {
    return a.d < b.d;
}
int main() {
    int n, m;
    cin >> n >> m;
    for(int i=0; i<n; i++) {
        cin >> node[i].d >> node[i].p;
    }
    sort(node, node+n, cmp);
    for(int i=0; i<n; i++) {
        if(i != 0) {
            Max[i] = max(Max[i-1], node[i].p);
        }
        else {
            Max[i] = node[i].p;
        }
    }
    for(int i=0; i<m; i++) {
        int tmp;
        cin >> tmp;
        int L = 0, R = n-1, Mid;
        while(L < R) {
            Mid = L + ((R - L) >> 1);
            if(node[Mid].d <= tmp) {
                L = Mid + 1;
            }
            else {
                R = Mid;
            }
        }
        if(node[L].d == tmp) {
            cout << Max[L] << endl;
        }
        else {
            cout << Max[L-1] << endl;
        }
    }
     
}

2.被3整除:

小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。

并且小Q对于能否被3整除这个性质很感兴趣。

小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。

解题思路分析;

打个表,其实规律一眼就能看出来,这种题真的不用去纠结为什么,等做完题了再想也来得及,规律:

1  12  123  1234  12345  123456  1234567……

0  1     1      0         1           1             0……

显然是011011011……的循环

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
    int l, r;
    while(cin >> l >> r) {
        l--;
        int nl = (l/3)*2 + (l%3) - 1;
        int nr = (r/3)*2 + (r%3) - 1;
        cout << nr - nl << endl;
    }
    return 0;
}

3.安置路灯

小Q正在给一条长度为n的道路设计路灯安置方案。

为了让问题更简单,小Q把道路视为n个方格,需要照亮的地方用'.'表示, 不需要照亮的障碍物格子用'X'表示。

小Q现在要在道路上设置一些路灯, 对于安置在pos位置的路灯, 这盏路灯可以照亮pos - 1, pos, pos + 1这三个位置。

小Q希望能安置尽量少的路灯照亮所有'.'区域, 希望你能帮他计算一下最少需要多少盏路灯。

解题思路分析:

其实只要做到没有两个灯之间重合,尽可能得不浪费灯在不需要照亮的地方,一定是能得到最终答案的。小编的做法就是,从左往右遍历,遇到一个需要照亮的地方,就在它的下一个位置放一盏灯,然后将这三个位置改为'X'即可。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000+5;
char str[maxn];
int main() {
    int T;
    cin >> T;
    while(T--) {
        int n;
        cin >> n >> str;
        int num = 0;
        for(int i=0; i<n; i++) {
            if(str[i] == '.') {
                num++;
                str[i] = str[i+1] = str[i+2] = 'X';
            }
        }
        cout << num << endl;
    }
}

4.迷路的牛牛

牛牛去犇犇老师家补课,出门的时候面向北方,但是现在他迷路了。虽然他手里有一张地图,但是他需要知道自己面向哪个方向,请你帮帮他。

解题思路分析:

这题应该是最简单的题了吧,首先四个L或R就相当于转了一圈,一个L一个R相当于没动,L和R的顺序改变不会影响结果,所以只需要稍微处理一下就可得到答案。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000+5;
char str[maxn];
char dir[4] = {'N', 'E', 'S', 'W'};
int main() {
    int n;
    cin >> n >> str;
    int nL = 0, nR = 0;
    for(int i=0; i<n; i++) {
        if(str[i] == 'L') {
            nL++;
        }
        else {
            nR++;
        }
    }
    nL %= 4;
    nR %= 4;
//  cout << nL << nR << endl;
    if(nR > nL) {
        cout << dir[(nR - nL)%4] << endl;
    }
    else if(nR < nL){
        cout << dir[4 - (nL - nR)%4] << endl;
    }
    else {
        cout << 'N' << endl;
    }
    return 0;
}

5.数对:

牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。

但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。

牛牛希望你能帮他计算一共有多少个可能的数对。

解题思路分析:

首先,答案中的数对里y一定是大于k的,对于每一个y,我们都能通过取模求得有多少个合法的x,所以我们只需要枚举所有的y即可得到答案。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int main() {
    int n, k;
    cin >> n >> k;
    if(k == 0) {
        cout << (LL)n*n << endl;
        return 0;
    }
    LL num = 0;
    for(int i=k; i<=n; i++) {
        int x = n / i;
        num += x * (i - k);
        if((n % i) >= k) {
            num += (n % i) - k + 1;
        }
    }
    cout << num << endl;
    return 0;
}

6.矩形重叠:

平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。

如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。

请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。

解题思路分析:

因为这个题小编当时在做的时候是没有做出这道题的,所以小编也不马后炮拿别人的思路来讲了,这题我看到很多人有很多不同的做法,这道题数据只有50,甚至在O(n^3)范围内都是能做出来的。

7.牛牛的闹钟:

牛牛总是睡过头,所以他定了很多闹钟,只有在闹钟响的时候他才会醒过来并且决定起不起床。从他起床算起他需要X分钟到达教室,上课时间为当天的A时B分,请问他最晚可以什么时间起床

解题思路分析:

首先这题需要做两个处理,第一,把带小时和分钟的两个变量存储为小时*60 + 分钟的一个变量,这样的转换是可以逆转的,。第二,把每一个时间都加上24小时再存储一遍,并把目标时间也加上24小时,这样处理可以灵活得解决过了一天小时从23又变为0这种情况,解决这个问题后只需要排序再进行二分查找即可得到答案。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100+5;
int t[maxn];
int main() {
    int n;
    cin >> n;
    for(int i=0; i<n; i++) {
        int a, b;
        cin >> a >> b;
        t[i] = a * 60 + b;
        t[n+i] = (a+24) * 60 + b;
    }
    sort(t, t+2*n);
    int x, A, B, T;
    cin >> x >> A >> B;
    T = (A+24) * 60 + B - x;
    int L = 0, R = 2*n-1, Mid;
    while(L < R) {
        Mid = L + ((R - L) >> 1);
        if(t[Mid] < T) {
            L = Mid + 1;
        }
        else {
            R = Mid;
        }
    }
    if(t[L] > T) {
        L--;
    }
    int H = t[L] / 60;
    int M = t[L] % 60;
    H %= 24;
    cout << H << " " << M << endl;
}

8.牛牛的背包问题:

牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。

牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。

牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。

解题思路分析:

这其实不是一个背包问题啊,题目是问我们有多少种方法,因为题目的数据只有35,那么仔细一分析,最多2^35的情况,那么我们可以直接DFS搜索答案,特殊处理w大于所有物品总和的情况即可。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 35;
LL v[40];
int n;
LL ans=0,w;
void dfs(int t, LL sum) {
    ans++;
    if(t == n-1){
        return ;
    }
    for(int i=t+1; i<n; i++) {
        if(sum+v[i] <= w) {
            dfs(i,sum+v[i]);
        }
    }
}
int main() {
    cin >> n >> w;
    LL sum = 0;
    for(int i=0; i<n; i++) {
        cin >> v[i];
        sum += v[i];
    }
    if(sum <= w) {
        ans = 1 << n;
    }
    else {
        dfs(-1, 0);
    }
    cout << ans << endl;
    return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值