网易2017春招实习生笔试编程题集合(C++方向)

这篇博客分享了网易2017年春季实习生笔试中C++方向的12道编程题,题目涵盖队列调整、饼干分配、双核处理等算法问题。博主提供了每道题目的解题思路和部分代码,难度适中,适合进阶练习。文章鼓励读者在GitHub上查看完整代码并讨论。
摘要由CSDN通过智能技术生成

挺早之前做好一直想写一篇博客分享一下,但是后来给忘了…C++方向一共十二道编程题,可能和别的方向有一些出入。题目总体的难度不大,有些题有些小坑,适合进阶者练练手,本文比较长,建议直接进github看代码,如有错误欢迎指出,也欢迎大家讨论!

代码都扔在Github了 -> Github

题目列表:

① 调整队列
② 分饼干
③ 双核处理
④ 堆砖块
⑤ 奇怪的表达式求值
⑥ 小易记单词
⑦ 工作安排
⑧ 凃棋盘
⑨ 消除重复元素
⑩ 赶去公司
⑪ 集合
⑫ 魔力手环

[Problem 1]:调整队列

在幼儿园有n个小朋友排列为一个队伍,从左到右一个挨着一个编号为(0~n - 1)。其中有一些是男生,有一些是女生,男生用’B’表示,女生用’G’表示。小朋友们都很顽皮,当一个男生挨着的是女生的时候就会发生矛盾。作为幼儿园的老师,你需要让男生挨着女生或者女生挨着男生的情况最少。你只能在原队形上进行调整,每次调整只能让相邻的两个小朋友交换位置,现在需要尽快完成队伍调整,你需要计算出最少需要调整多少次可以让上述情况最少。例如:GGBBG->GGBGB->GGGBB
这样就使之前的两处男女相邻变为一处相邻,需要调整队形2次
输入描述 :
输入数据包括一个长度为n且只包含G和B的字符串.n不超过50.
输出描述 :
输出一个整数,表示最少需要的调整队伍的次数
输入例子 :
GGBBG
输出例子 :
2

这题只分两种情况,男女相挨着的情况最少,那么就是G都在左边或者B都在左边,两种情况模拟一下然后min就是答案了。
实现代码:

#include<iostream>
//#include<map>
#include<algorithm>
#include<string>
#include<vector>
//#include<numeric>
//#include<cmath>
//#include<set>

using namespace std;

string QUEUE;
int result, Num_G = 0, Num_B = 0;
vector<int>Result_G, Result_B;
int main() {
    cin >> QUEUE;
    size_t len = QUEUE.size();
    int i = 0;
    int sum_G = 0, sum_B = 0;
    //auto it = QUEUE.begin(), END = QUEUE.end();
    while (i < len) {
        if (QUEUE[i] == 'G') {
            ++Num_G; Result_G.push_back(i);
        }
        if (QUEUE[i] == 'B') {
            ++Num_B; Result_B.push_back(i);
        }
        ++i;
    }
    for (i = 0; i < Num_G; ++i)sum_G += (Result_G[i] - i);
    for (i = 0; i < Num_B; ++i)sum_B += (Result_B[i] - i);
    result = min(sum_B, sum_G);
    cout << result << endl;
    return 0;
}

[Problem 2]:分饼干

易老师购买了一盒饼干,盒子中一共有k块饼干,但是数字k有些数位变得模糊了,看不清楚数字具体是多少了。易老师需要你帮忙把这k块饼干平分给n个小朋友,易老师保证这盒饼干能平分给n个小朋友。现在你需要计算出k有多少种可能的数值
输入描述 :
输入包括两行:
第一行为盒子上的数值k,模糊的数位用X表示,长度小于18(可能有多个模糊的数位)
第二行为小朋友的人数n
输出描述 :
输出k可能的数值种数,保证至少为1
输入例子 :
9999999999999X
3
输出例子 :
4

最笨也是最直接的方法当然是X用0~9然后挨个试一遍,牛客讨论区看到有人这样能AC,但是我死活过不了不知道为什么…然后用了另一种方法,是从讨论区看到的思路,1个数在除以一个数的过程中,是从前往后一位一位除的,能否除的尽,要看前面的余数和当前的数的组合能否除的尽,所以要记录前面一位所有的余数可能性。比如 :

X2
2

X除2的余数可能是0 ,1,是0的可能性为X=0,2,4,6,8 五种,取1的可能性为X=1,3,5,7,9 也是五种,这个时候再看个位数的2,2和前面的余数0/1的组合为02/12,也就是说到了这一位余数为0的可能性为上一位余数为0/1两种情况总数的和,因为02,12余2都是0,k=5+5=10种。
感觉有点类似于推公式,找规律,不那么容易想到。
也看到有另一种思路的,将k分拆为多个数,比如123X45,那么可能总数就是123000+X45(X枚举0~9),若(123000%n+X45%n)=n的倍数,则此种情况成立,最后算一个总和,大家可以尝试一下。
实现代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<ctype.h>
#include<sstream>
//#include<numeric>
//#include<cmath>
//#include<set>

using namespace std;

long long sync[10001], remain[10001];   //每一位数对应余数取值的可能性
int main() {
    string s;
    int n;
    cin >> s;
    cin >> n;
    sync[0] = 1;
    int s_size = s.size();
    for (int i = 0; i < s_size; ++i) {
        memset(remain, 0, sizeof(remain));
        for (int j = 0; j < n; j++) {       //这一位所能取的余数的可能性(0...n-1)
            for (int k = 0; k < 10; k++) {    //这一位能取的数,当然是0~9啦
                if (isdigit(s[i]) && s[i] - '0' != k) continue;
                //isdigit 判断是否为0~9的数字
                //若该位为k,则计算所有可能取值,否则只计算这一种取值
                remain[((j * 10) + k) % n] += sync[j];
                //计算当前值和前一位余数的取值组合产生的余数
            }
        }
        memcpy(sync, remain, sizeof(sync));  //与余数对应的取值同步
    }
    cout << sync[0] << endl;  //最后一位余数为0的的取值
}

[Problem 3]:双核处理

一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
输入描述 :
输入包括两行:
第一行为整数n(1 ≤ n ≤ 50)
第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。
输出描述 :
输出一个整数,表示最少需要处理的时间
输入例子 :
5
3072 3072 7168 3072 1024
输出例子 :
9216

其实这是一道简单的动态规划题,双核处理,我们只要处理其中的一半,然后和剩下的一半对比时间哪个更少就行了,把它转化为经典的0-1背包模型,其实就是代价所获价值都是length[i],思路在注释里了,solve部分优化了空间,优化的部分建议大家参考hihocoder-1038这道题,过程写得可以说是非常详细了1038# 0-1背包
实现代码:

#include<iostream>
//#include<map>
#include<algorithm>
//#include<string>
#include<vector>
#include<numeric>
//#include<cmath>
//#include<set>
using namespace std;
const int MAX_SIZE = 
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值