网易2017春招笔试真题编程题集合

本文解析了多个算法题目,涉及双核处理任务调度、队伍调整、棋盘涂画等问题,提供了详细的思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

双核处理
一种双核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
思考:这道题大致意思是把这些任务分为两部分,分别有两个cpu处理, 最小时间取决于处理时间相当对长的那个cpu所消耗的时间。目录是把数据分为两部分, 这两部分的和的差值最小!利用01背包可以解此题,下面分别用一维和二维数组实现。

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 55;
int w[maxn];//背包的容量和价值相等
int n;//n个物品
int W = 0;//背包容量
int dp[maxn][5000*25];

int DP() {
    int Size = W/2;
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <= Size; j++) {
            if(j < w[i]) {
                dp[i][j] = dp[i-1][j];
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + w[i]);
            }
        }
    }
    return dp[n][Size];
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &w[i]);
        w[i] /= 1024;
        W += w[i];
    }
    int res = DP();
    cout << max(res, W-res) * 1024 << endl;
    return 0;
}
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 55;
int n;//n个物品
int f[5000*25];
int w[maxn];//背包的容量和价值相等
int W = 0;//背包容量

int DP() {
    int half = W/2;
    for(int i = 1; i <= n; i++) {
        for(int j = half; j >= 0; j--) {
            if(j >= w[i]) {
                f[j] = max(f[j], f[j-w[i]] + w[i]);
            }
        }
    }
    return f[half];
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &w[i]);
        w[i] /= 1024;
        W += w[i];
    }
    int res = DP();
    cout << max(res, W-res)*1024 << endl;
    return 0;
}

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

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int work(string s, char ch);
string str;

int main()
{
    cin >> str;
    int n = work(str, 'G');
    int m = work(str, 'B');
    cout << min(n, m) << endl;
    return 0;
}

int work(string s, char ch) {
    int indexSum = 0;
    int num = 0;
    for(int i = 0; i < (int)s.length(); i++) {
        if(s[i] == ch) {
            num++;
            indexSum += i;
        }
    }
    int res = indexSum - (num*(num-1))/2;
    return res;
}

凃棋盘
小易有一块n*n的棋盘,棋盘的每一个格子都为黑色或者白色,小易现在要用他喜欢的红色去涂画棋盘。
小易会找出棋盘中某一列中拥有相同颜色的最大的区域去涂画,帮助小易算算他会涂画多少个棋格。
输入描述 :
输入数据包括n + 1行:
第一行为一个整数n(1 ≤ n ≤ 50), 即棋盘的大小
接下来的n行每行一个字符串表示第i行棋盘的颜色,’W’表示白色,’B’表示黑色
输出描述 :
输出小易会涂画的区域大小
输入例子 :
3
BWW
BBB
BWB
输出例子 :
3
思路:B转为0, W转为1。然后每一列为一个数组单独处理。

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 55;
int mat[maxn][maxn];
///B for 0 W for 1
int n;
int work(vector<int> &v) {
    int num[maxn];
    num[0] = 1;
    for(unsigned i = 1; i < v.size(); i++) {
        if(v[i] == v[i-1]) {
            num[i] = num[i-1] + 1;
        } else {
            num[i] = 1;
        }
    }
     int maxValue = -1;
     for(int i = 0; i < n; i++) {
        maxValue = max(maxValue, num[i]);
     }
     return maxValue;
}
int main()
{
    cin >> n;
    string str;
    for(int i = 0; i < n; i++) {
        cin >> str;
        for(int j = 0; j < (int)str.length(); j++) {
            if(str[j] == 'B') {
                mat[i][j] = 0;
            } else {
                mat[i][j] = 1;
            }
        }
    }
    int maxValue = -1;
    vector<int> V;
    for(int j = 0; j < n; j++) {
        for(int i = 0; i < n; i++) {
            V.push_back(mat[i][j]);
        }
        int res = work(V);
        maxValue = max(maxValue, res);
        V.clear();
    }
    cout << maxValue << endl;
    return 0;
}
/**
测试数据:
3
BWW
BBB
BWB
3

8
BBWWBBWW
BBWWBBWW
WWBBWWBB
WWBBWWBB
BBWWBBWW
BBWWBBWW
WWBBWWBB
WWBBWWBB
2
**/

消除重复元素
小易有一个长度为n序列,小易想移除掉里面的重复元素,但是小易想是对于每种元素保留最后出现的那个。小易遇到了困难, 希望你来帮助他。
输入描述 :
输入包括两行:
第一行为序列长度n(1 ≤ n ≤ 50)
第二行为n个数sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔
输出描述 :
输出消除重复元素之后的序列,以空格分隔,行末无空格
输入例子 :
9
100 100 100 99 99 99 100 100 100
输出例子 :
99 100
思路:用set判断重复, 用stack保持其有序性。

#include <iostream>
#include <cstdio>
#include <set>
#include <vector>
#include <stack>
using namespace std;

int main()
{
    int n;
    int read;
    cin >> n;
    set<int> mySet;
    vector<int> V;
    stack<int> resultStack;
    for(int i = 0; i < n; i++) {
        cin >> read;
        V.push_back(read);
    }
    int len = V.size();
    set<int>::iterator it;
    for(int i = len-1; i >= 0; i--) {
        it = mySet.find(V[i]);
        if(it != mySet.end()) {
            continue;
        } else {
            mySet.insert(V[i]);
            resultStack.push(V[i]);
        }
    }
    int top = resultStack.top();
    cout << top;
    resultStack.pop();
    while(!resultStack.empty()) {
        cout << " " << resultStack.top() ;
        resultStack.pop();
    }
    return 0;
}

工作安排
现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,
比如:045,表示某位工程师能够胜任0号,4号,5号工作)。现在需要进行工作安排,
每位工程师只能被安排到自己能够胜任的工作当中去,两位工程师不能安排到同一项工作当中去。
如果两种工作安排中有一个人被安排在的工作序号不一样就被视为不同的工作安排,现在需要计算出有多少种不同工作安排计划。
输入描述:
输入数据有n+1行:
第一行为工程师人数n(1 ≤ n ≤ 6)
接下来的n行,每行一个字符串表示第i(1 ≤ i ≤ n)个人能够胜任的工作(字符串不一定等长的)
输出描述:
输出一个整数,表示有多少种不同的工作安排方案
输入例子:
6
012345
012345
012345
012345
012345
012345
输出例子:
720
思考:此题数据量不大,代码用的dfs,可以思考如果增大数据量该怎么做。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
void dfs(int index);
const int maxn = 10;
vector<string> v;
int n;
bool vis[maxn]; //记录是否分配过
int totalMethod = 0;

int main()
{
    cin >> n;
    getchar();
    string str;
    for(int i = 0; i < n; i++) {
        getline(cin, str);
        v.push_back(str);
    }
    memset(vis, false, sizeof(vis));
    dfs(0);
    cout << totalMethod << endl;
    return 0;
}
//index 代表是下标为index的人
void dfs(int index) {
    string str = v[index];
    for(unsigned i = 0; i < str.length(); i++) {
        int id = str[i]-'0';
        if(!vis[id]) {
            if(index == n-1) {
                totalMethod++;
                continue;
            } else {
                vis[id] = true;
                dfs(index+1);
                vis[id] = false;
            }
        }
    }
}

小易记单词
小易参与了一个记单词的小游戏。游戏开始系统提供了m个不同的单词,小易记忆一段时间之后需要在纸上写出他记住的单词。小易一共写出了n个他能记住的单词,如果小易写出的单词是在系统提供的,将获得这个单词长度的平方的分数。
注意小易写出的单词可能重复,但是对于每个正确的单词只能计分一次。
输入描述 :
输入数据包括三行:
第一行为两个整数n(1 ≤ n ≤ 50)和m(1 ≤ m ≤ 50)。以空格分隔
第二行为n个字符串,表示小易能记住的单词,以空格分隔,每个单词的长度小于等于50。
第三行为m个字符串,系统提供的单词,以空格分隔,每个单词的长度小于等于50。
输出描述 :
输出一个整数表示小易能获得的分数
输入例子 :
3 4
apple orange strawberry
strawberry orange grapefruit watermelon
输出例子 :
136

#include <iostream>
#include <cstdio>
#include <string>
#include <set>
using namespace std;
const int maxn = 55;
set<string> mem;
set<string> provide;
int n, m;
int main() {
    cin >> n >> m;
    char read[maxn];
    for(int i = 0; i < n; i++) {
        scanf("%s", read);
        string str = string(read);
        mem.insert(str);
    }
    for(int i = 0; i < m; i++) {
        scanf("%s", read);
        string str = string(read);
        provide.insert(str);
    }
    set<string>::iterator it;
    set<string>::iterator pit;
    int score = 0;
    for(it = mem.begin(); it != mem.end(); it++) {
        pit = provide.find(*it);
        if(pit != provide.end()) {
            string s = *it;
            score += s.length() * s.length();
        }
    }
    cout << score << endl;
    return 0;
}

奇怪的表达式求值
常规的表达式求值,我们都会根据计算的优先级来计算。比如, / 的优先级就高于 + -。但是小易所生活的世界的表达式规则很简单,从左往右依次计算即可,而且小易所在的世界没有除法,意味着表达式中没有 / ,只有(+, -和 )。现在给出一个表达式,需要你帮忙计算出小易所在的世界这个表达式的值为多少
输入描述 :
输入为一行字符串,即一个表达式。其中运算符只有 - , +, *。参与计算的数字只有0~9.
保证表达式都是合法的,排列规则如样例所示。
输出描述 :
输出一个数,即表达式的值
输入例子 :
3 + 5 * 7
输出例子 :
56
思路:题目不难,首先我是把操作数和运算符分开
操作数用dequeue维护可以在前端插入。

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <deque>
using namespace std;
deque<int> num;
queue<char> operate;
//把数字和运算符分开
void separate(string &str) {
    for(int i = 0; i < (int)str.length(); i++) {
        if(str[i]>= '0' && str[i] <= '9') {
            num.push_back(str[i]-'0');
        } else {
            operate.push(str[i]);
        }
    }
}
int calculate() {
    while(!num.empty()) {
        if(num.size() == 1) break;
        int x = num.front();
        num.pop_front();
        int y = num.front();
        num.pop_front();
        char ch = operate.front();
        operate.pop();
        int z = 0;
        switch(ch) {
            case '+':
                z = x + y;
                break;
            case '-':
                z = x - y;
                break;
            case '*':
                z = x * y;
                break;
        }
        num.push_front(z);
    }
    int res = num.front();
    return res;
}
int main()
{
    string str;
    getline(cin, str);
    separate(str);
    int res = calculate();
    cout << res << endl;
    return 0;
}
/**
7*9-2*0+2
输入例子 :
3 + 5 * 7
输出例子 :
56
**/

另外一篇博客:http://blog.youkuaiyun.com/cqk0100/article/details/73010307

2023年3月11日,美团春季招聘笔试中共包含五道编程题目。以下是对每道题目的简要说明: 1. 题目一:这道题目要求解决一个数字统计的问题。可能涉及到的知识点包括数据结构、循环和条件判断等。解决问题的思路可能是使用字典等数据结构来保存统计结果,并使用循环逐个读取输入数据并进行统计。 2. 题目二:这道题目可能是一个字符串处理的问题。需要使用字符串的方法进行操作,如提取、拼接、查找和替换等。可能的解决思路包括使用正则表达式、切片和遍历等。 3. 题目三:这道题目可能涉及到算法和数据结构的知识。可能是一道涉及到数组、链表、树等数据结构的问题。解决思路可能包括遍历、递归、搜索和排序等。 4. 题目四:这道题目可能是一个动态规划的问题。需要根据给定的条件和规则,通过动态规划的方式求解问题。解决思路包括定义状态和转移方程,使用递推或记忆化搜索进行求解。 5. 题目五:这道题目可能是一个图论或网络问题。需要根据给定的图或网络结构,解决一个相关的问题。可能涉及到广度优先搜索、深度优先搜索、最短路径等知识。解决思路可能包括使用图或网络的相关算法进行求解。 以上只是对这五道编程题目的一些可能情况进行的简要描述,具体的题目内容可能会有所不同。希望这些信息能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值