网易2021校招笔试-C++开发工程师(正式第一批)

一、树上摘樱桃(易)

1.1 题目描述

二叉树上的叶子节点定义为“樱桃”。现在需要找出二叉树上有多少个有两颗“樱桃”的结点。
输入描述:
第一行两个正整数m, n,空格分开,分别代表总共有树上有多少个节点,树上有多少条边,2<=m<=100, 1<=n<=100
下面有n行,每行为3个部分,用空格分割,第一个数字为某非叶子节点的id, 第二个为该边为left还是right,第三个为子节点的id
注意:节点id彼此不会重复,id 1为根节点

输入:

10 9
1 left 2
1 right 3
2 left 4
2 right 5
3 right 6
6 left 7
6 right 8
8 left 9
8 right 10

结果:2

1.2 题目分析

遍历所有节点,计算一共有多少个节点(有两个孩子且这两个孩子为叶子结点)

1、如何存储二叉树;(vector<pair<string, int> > edge[N + 1]); string:左子树or右子树

1.3 代码实现

#include<iostream>
#include<vector>
#include<map>
#include<string>
using namespace std;
const int maxn = 102;

vector<pair<string, int> > edge[maxn];
int m, n; // m代表节点数  n代表边数

bool check(int x){ // 检查节点x是否为叶子节点
    if(edge[x].size() == 0)
        return true;
    return false;
}

int main()
{
    cin >> m >> n;
    string s;
    int id1, id2;
    for(int i = 0; i < n; i++){
        cin >> id1 >> s >> id2;
        edge[id1].push_back(make_pair(s, id2));
    }
    int res = 0; // 记录最终结果
    for(int i = 1; i <= m; i++){
        if(edge[i].size() == 2 && check(edge[i][0].second) && check(edge[i][1].second))
            res++;
    }
    cout << res << '\n';
    return 0;
}

二、特征排列组合(递归)

2.1 题目描述

输入描述:
输入n,表示总共有多少组不同的特征,1<=n<=100
下面有n行,每一行特征为该组的所有取值,用空格区分, 每一行的特征值数量不大于100,每个特征值为英文或者数字组合成的字符串。
输出描述:
输出为排列组合后的所有组合值,每个组合值为一行,不同组的特征值之间用"-"连接,显示顺序保持的原特征的显示顺序关系(参照例子)

输入:

3
man woman
coder gamer painter
phd

输出:

man-coder-phd
woman-coder-phd
man-gamer-phd
woman-gamer-phd
man-painter-phd
woman-painter-phd

2.2 题目分析

1、如何输入?见代码
2、不可能为每一种特征都写一个for循环,因此,想到递归。
3、从输出顺序可以看出此为倒序DFS。

2.3 代码实现

#include<iostream>
#include<vector>
#include<string>
using namespace std;
const int maxn = 102;

int n;
vector<string> v[maxn];

void dfs1(int x, string path){  // 正序DFS
    if(x > n){
        cout << path << '\n';
        return ;
    }
    for(int i = 0; i < v[x].size(); i++){
        if(x != 1)
            dfs1(x + 1, path + '-' + v[x][i]);
        else
            dfs1(x + 1, path + v[x][i]);
    }
}

void dfs2(int x, string path){  // 倒序DFS
    if(x == 0){
        cout << path << '\n';
        return ;
    }
    for(int i = 0; i < v[x].size(); i++){
        if(x != n)
            dfs2(x - 1, v[x][i] + '-' + path);
        else
            dfs2(x - 1, v[x][i] + path);
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++){
        string s;
        while(cin >> s){
            v[i].push_back(s);
            if(cin.get() == '\n')
                break;
        }
    }
    dfs1(1, "");
    dfs2(n, "");
    return 0;
}

三、特殊的编辑距离(动态规划DP)

3.1 题目描述

在自然语言处理的过程中,经常需要判断一个字符串和另外一个字符串之间的一个相似程度,其中常见的一个指标就是编辑距离,即一个字符串最少经过多少次“增删改”某个字符,可以变为另一个字符串。如“abc”与“ac”的编辑距离为1,是因为在a和c中间“增加”一个b即可。如“abcd”与“axc”的编辑距离为2,是因为把“abcd”的b修改为x,然后再删除d即可,共2次操作。
但是在某种场景中,编辑距离定义为词粒度的。比如句子A “I am a coder”与句子B “hello , I am a singer”之间,对于句子A可以通过添加"hello"和符号",“, 并替换"coder"为"singer”,共3个操作得到句子B。所以可得其基本的编辑距离为3。
在本题中,特别地,对于部分词,比如标点符号“, ”、"hello"对于句子语义的影响并不重要,这部分称之为停用词,这部分可以在匹配的过程中被跳过。比如对于句子A “I am a coder”与句子B “hello , I am a singer”,如果加入了停用词的影响,那编辑距离从3降到1。
所以目标是可以有选择性地跳过停用词的情况下,问最小的编辑距离是多少。

输入描述:
共3行
第一行为停用词列表,用空格区分
第二行为句子A,所有词可以用空格区分,词数不超过10000
第三行为句子B,所有词可以用空格区分,词数不超过10000

输入:
hello , ?
I am a boy
are you a girl ?
输出:3

3.2 题目分析

1、三种操作:增加、删除、修改;
2、既然停用词对结果没影响,那么直接将两句话中的停用词全部删除;
3、动态规划

3.3 代码实现

#include<iostream>
#include<string>
#include<vector>
#include<unordered_set>
#include<algorithm>
using namespace std;

unordered_set<string> stop;
vector<string> A;
vector<string> B;
int main()
{
    string s;
    while(cin >> s){
        stop.insert(s);
        if(cin.get() == '\n')
            break;
    }
    while(cin >> s){
        if(!stop.count(s))
            A.push_back(s);
        if(cin.get() == '\n')
            break;
    }
    while(cin >> s){
        if(!stop.count(s))
            B.push_back(s);
        if(cin.get() == '\n')
            break;
    }
    
    int lengthA = A.size();
    int lengthB = B.size();
    vector<vector<int> > dp(lengthA + 1, vector<int>(lengthB + 1, 0));
    // dp[i][j]表示表示A串从第0个字符开始到第i个字符和B串从第0个字符开始到第j个字符,这两个字串的编辑距离, A和B是从下标为0处开始的
    for(int i = 0; i <= lengthA; i++)
        dp[i][0] = i;
    for(int j = 0; j <= lengthB; j++)
        dp[0][j] = j;
    for(int i = 1; i <= lengthA; i++)
        for(int j = 1; j <= lengthB; j++){
            // 此处为何是A[i-1]和B[j-1]
            // 因为A串的第i个字符即为A[i-1]
            if(A[i - 1] == B[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
            else
                dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
                // dp[i - 1][j - 1] + 1  替换(修改)
                // dp[i - 1][j] + 1   删掉字符串a最后一个字符a[i]
                // dp[i][j - 1] + 1   给字符串添加b最后一个字符
        }
    cout << dp[lengthA][lengthB] << '\n';
    return 0;
}

四、组合幸运数字(难)

4.1 题目描述

小易的幸运数字是7,现有一个整数数组 nums,请你找出并返回能被七整除的子集合的最大和,如果找不到则返回-1。

输入描述:
一个正整数数组列表nums,用空格区分,1<=length(nums)<=100000,sum(nums) <= 1000000000

7 3 1 4
输出:14 (3 4 7)
6 5
输出:-1 (没有)

4.2 题目分析

1、学会思路;
2、学会for(int v : vector< int>(dp))。

4.3 代码实现

#include<iostream>
#include<vector>
using namespace std;
const int maxn = 100002;

vector<int> nums;
int main()
{
    int cur;
    while(cin >> cur)
        nums.push_back(cur);
    vector<int> dp(7, 0); // dp[i] 余数为i的最大和
    for(int num : nums)
        for(int v : vector<int>(dp)){
            dp[(num + v) % 7] = max(dp[(num + v) % 7], num + v);
        }
    if(dp[0] == 0)
        cout << "-1" << '\n';
    else
        cout << dp[0] << '\n';
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,测试开发工程师笔试题的复习内容包括以下几个方面: 1. 不定项选择题: 这部分考察的是基础知识,包括SV基本数据类型、UVM的基础知识等。 2. 简答题:这部分考察的是对特定问题的简要回答,包括对数组和队列的优缺点以及应用场景、sequence和sequencer的机制、testcase如何发送参数到sequence等。 3. 编程题:这部分考察的是编程能力,包括解决具体问题的编程思路和代码实现。例如,不使用randc产生随机数,要求数组中的数不能重复且第八个数为8、最大值为9。 4. 画图题:这部分考察的是对特定概念或流程的图示能力,包括APB的读写操作时序图、tb的框架图以及验证的流程图等。 综上所述,测试开发工程师笔试题的复习内容主要包括基础知识、简答题的回答能力、编程题的解决思路和代码实现能力以及画图题的图示能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [互联网行业面试笔试真题资料BAT谷歌微软等笔试面试真题复习资料合集200MB.zip](https://download.csdn.net/download/GZXGYZ/16604785)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [海康威视 2024届实习生 应用软件开发工程师 Java 在线笔试](https://blog.csdn.net/guliguliguliguli/article/details/130571927)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【2023芯动科技提前批笔试题】~ 题目及参考答案](https://blog.csdn.net/qq_40549426/article/details/125948868)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了无痕-W

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值