OPPO 2024届校招正式批笔试题-AI/算法类(C卷) 2024/12/8
1.执行以下程序,输出结果为(False)
1 2 3 |
|
id()函数可以返回对象的内存地址,由于l1.extend(l2)会在原l1的基础上合并l2,也就是说,使用l1.extend(l2)后,l1的值变为[1,2,3,4],且地址不会发生改变,所以很容易误认为输出结果为True,实际上,l1.extend(l2)是没有返回值的,或者说,返回值为None,因此本题实际上是判断id(l1) == id(None)的值,显然结果为False
2.执行以下程序,输出结果为([[2,1], [1,1]])
1 2 3 4 5 6 |
|
序列的*是对序列的元素进行复制,不是对序列直接复制,因此循环产生的中间变量r的值为[1,1],而不是[[1],[1]],故变量l实际上是一个二维列表而不是三维列表。
3.此代码的运行结果,正确的是(B)
1 2 3 4 5 6 7 8 9 10 11 |
|
A.<p class="one">1</p>
B.[<p class="one">1</p>, <div class="one">
<p id="two">2</p>
<p class="one">3</p>
</div>, <p class="one">3</p>]
C.[<p class="one">1</p>, <div class="one"></div>, <p class="one">3</p>]
D.[<p class="one">1</p>, <p class="one">3</p>]
此代码用BeautifulSoup将html字符串解析成BeautifulSoup对象,能够更加方便的从网页中抓取数据。select函数可以用选择器获取所有符合条件的标签对象,返回结果类型是结果集ResultSet,所以A选项错误。
在选择器中,.表示类选择器,#表示id选择器。此代码中,'.one'表示类选择器,会选择所有class="one"的标签对象,需要注意的是,获取到的div标签对象包含它所有嵌套的内容
4.在某些网络结构中,开发者会选择使用两个 3x3 卷积核代替一个 5x5 的卷积核。对于这个操作,下列说法正确的是(D)
A.在保证网络深度不变的前提下,扩大了感受野
B.在保证参数量不变的前提下,扩大了感受野
C.在保持参数量不变的前提下,提升了网络的深度
D.在保证感受野不变的前提下,降低了参数量
使用两个 3x3 卷积核比只使用一个 5x5 卷积核多了一层卷积层,因此网络深度增加,A 选项错误;以输入图像的尺寸为 5x5 的情况为例,一层 3x3 卷积核的感受野为 3x3,两层 3x3 卷积核的感受野则为 5x5,而一层 5x5 卷积核的感受野为 5x5,两者相等,事实上,这样的替换不会改变感受野,B 选项错误;假设输入的通道数为 m,输出的通道数为 n,则两个 3x3 卷积核的参数量为 2*3*3*m*n = 18mn,而一个 5x5 卷积核的参数量为 5*5*m*n = 25mn,因此替换后参数量有所下降,C 选项错误;根据之前的分析可知,这样的替换操作能够在保证感受野不变的前提下降低参数量,D 选项正确。
5.下列关于辅助索引说法错误的是(B)
A.如果一条关系可以有不止一条包含相同搜索码值的记录,则该搜索码称为非唯一性搜索码
B.辅助索引可以是稀疏的,且每个搜索码值可以多个索引项
C.辅助索引只存储部分搜索码值,则具有中间搜索码值的记录可能存在于文件中的任何位置
D.非唯一性搜索码上的辅助索引中的指针不会直接指向记录
非唯一性搜索码就是指如果一种关系可以有不止一条包含相同搜索码值的记录也就是两条或者多条记录对于索引属性可以具有相同的值,故A排除;
而辅助索引必须是稠密的,对每个搜索码值都有一个索引项,并且对文件中的每条记录都有一个指针,而聚集索引可以是稀疏的存储部分的搜索码值,故B错误;
同时如果辅助索引值存储部分搜索码值,则具有中间搜索码值的记录可能存在于文件中的任何位置,通常是扫描整个文件去发现这些记录,故C排除;
在非唯一性搜索码上实现辅助索引,其指针不会直接指向记录,而是指向一个桶,桶中包含指向文件的指针,故D排除
6.小欧有两个六个面的骰子,请问第一次投掷的点数大于第二次投掷点数的概率是多少?(5/12)
第二次有三种情况,小于第一次等于第一次和大于第一次,其中大于和小于的概率是一样的,等于的概率是1/6,那么大于的概率就是5/6除2=5/12
7.下列关于 XGBoost 的说法,错误的是(A)
A.XGBoost 支持单颗树粒度的并行
B.XGBoost 支持特征抽样
C.XGBoost 在代价函数里加入了正则项
D.XGBoost 支持对缺失值的自动处理
XGBoost 在特征粒度上支持并行,A 说法错误;
XGBoost 支持列抽样,即特征抽样,B 说法正确;XGBoost 在代价函数里加入了正则项用于控制模型的复杂度,C 说法正确;XGBoost 对于特征的值有缺失的样本,可以自动学习出它的分裂方向
8.下列关于半监督学习的说法,正确的有(B)
A.直推学习假定训练数据集中的未标记数据并非待预测数据
B.半监督学习的训练集同时包含有标记样本数据和未标记样本数据
C.纯半监督学习假定学习过程中的未标记数据就是待预测数据
D.其余选项均正确
半监督学习可以进一步划分为纯半监督学习和直推学习,其中,纯半监督学习假定训练数据集中的未标记数据并非待预测数据,直推学习假定学习过程中的未标记数据就是待预测数据;让学习过程不依赖外界的咨询交互,自动利用未标记样本所包含的分布信息的方法便是半监督学习,即训练集同时包含有标记样本数据和未标记样本数据,B 选项正确。
9.关于InnoDB存储引擎,以下说法正确的是(A)
A.InnoDB存储引擎的逻辑结构最高层次是表空间,所有的数据都放在表空间中
B.在InnoDB存储引擎中,磁盘管理的最小逻辑单元是行
C.在InnoDB存储引擎中,页大小可以通过参数 innodb_page_size更改,默认大小为4KB
D.在InnoDB存储引擎中,区是由页组成的连续空间,其大小是2MB
磁盘管理的最小逻辑单元是页,默认大小是16KB,每个区的大小都是1MB,每个区都包含64个连续的页。
10.下列哪一项在神经网络中引入了非线性(B)
A.随机梯度下降
B.修正线性单元(ReLU)
C.卷积函数
D.其余选项都不正确
11.C++11 中有如下 Employee 类代码,则下面选项中不能正确创建 Employee 对象的是(A)
1 2 3 4 5 6 7 8 9 |
|
A.Employee emp;
B.Employee emp = Employee("Jams", 20000.0);
C.Employee *emp = new Employee("Jams", 20000.0);
D.Employee emp = {"Jams", 20000.0};
A选项错误,调用无参的默认构造函数,因定义了构造函数因此默认构造函数不存在
12.下面关于 C++ 中函数指针的说法错误的是(C)
A.函数和普通的数据一样也具有地址,函数的地址是存储其机器语言代码的内存开始地址
B.声明指向函数的指针时,必须指定指针指向的函数类型
C.要获取函数的地址,只需要使用函数名即可,不能通过&的方式获取
D.假设pf是函数指针,则pf() 和 (*pf)() 都可以调用该函数指针所指向的函数
13.Linux 中,有文本文件 file.txt,想要查找出包含 "test" 或 "taste" 两个单词的行并显示对应行号,下面命令正确的是(A)
A.grep -n 't[ae]st' file.txt
B.grep -n '^t[ae]st' file.txt
C.grep -n 't(ae)st' file.txt
D.grep -n 'taste&test' file.txt
14.下面关于 Linux 中的内存映射的说法错误的是(D)
A.内存映射是指将文件的内容映射到进程的虚拟地址空间
B.进程可通过访问虚拟内存来访问文件的内容
C.对映射内存所做的更改会体现在映射的文件中
D.内存映射不会消耗进程的虚拟地址空间
15.判断两个单链表是否相交的最优操作是(B)
A.遍历第一个链表的每个结点,依次与第二个链表的每个结点比较,如果存在相同的结点,则两个链表相交
B.遍历第一个链表,将每个结点的指针保存到一个哈希表中,然后遍历第二个链表,检查每个结点是否在哈希表中,如果存在,则两个链表相交
C.遍历第一个链表,将最后一个结点的指针指向第二个链表的头节点,然后判断第二个链表是否存在环,如果存在环,则两个链表相交
D.遍历第一个链表,将最后一个结点的指针指向第二个链表的头节点,然后判断第一个链表是否存在环,如果存在环,则两个链表相交
选项C和选项D是通过改变链表的结构来判断两个链表是否相交,但会改变原有的链表结构,不符合实际应用场景。
16.已知一个有序表(-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16),当进行在中间值位置向下取整的二分查找值为0的元素时,查找成功的比较次数为( 4)
17.编程题1-小欧逛商店
小欧准备去商店买东西,商店中有𝑛n个物品从左向右摆成一排,第𝑖个物品的体积为𝑎𝑖,价值为𝑏𝑖。小欧有一个容量为𝑥的背包,她每次看到能装进背包里的物品都会装进去,如果装不进去就跳过这个物品。
小欧想知道,她总共能买多少价值的物品?
#include <iostream>
using namespace std;
int n,x;
long long ans;
int main() {
cin>>n>>x;
int a,b;
for(int i=0;i<n;i++){
cin>>a>>b;
if(x>=a) {
ans+=b;
x-=a;
}
}
cout<<ans;
return 0;
}
18.编程题2-小欧的字符串构造
小欧有一个字符串 𝑠 ,她想构造一个长度为 𝑘 的字符串 𝑡t ,使得 𝑠+𝑡或 𝑡+𝑠拼成的字符串是回文串。
如果可以构造,则输出 𝑡,若无法构造,请输出 -1。
#include<bits/stdc++.h>
using namespace std;
string s,t;
int k;
bool check(string s){
//检查是否为回文串
string x=s;
reverse(s.begin(),s.end());
return s==x;
}
int main() {
cin>>s>>k;
//构造一个长度为k的字符串t 使得s+t或者t+s有一个为回文串即可
int l=s.size();
if(k==l){
reverse(s.begin(),s.end());
cout<<s;
return 0;
}else if(k<l){
//检查两种情况
string temp;
for(int i=0;i<k;i++){
temp+=s[i];
}
reverse(temp.begin(),temp.end());
// cout<<s+temp<<endl;
if(check(s+temp)) {
cout<<temp;
return 0;
}else {
//检查另一种情况
temp.clear();
for(int i=l-1;i>=l-k;i--){
temp+=s[i];
}
// cout<<temp+s<<endl;
if(check(temp+s)){
cout<<temp;
return 0;
}
}
}
cout<<"-1";
return 0;
}
19.编程题3-小欧皇
小欧正在扮演一个中世纪的皇帝。地图上有𝑛n个城市,其中有𝑚m条道路,每条道路连接了两个城市。
小欧占领了其中一些城市。如果两个城市可以通过若干条道路互相到达,且这些道路经过的城市都是小欧占领的,那么这两个城市之间就可以通过经商获得收益11。请注意,每两个城市之间的收益只会被计算一次。
现在,小欧准备占领一个未被占领的城市,使得总收益最大化。你能帮帮她吗?
输入描述
第一行输入两个正整数n和m,代表城市数量和道路数量。
第二行输入一个长度为n的 01 串。第i个字符为'0'代表小欧未占领该城市,'1'代表小欧占领了该城市。
接下来的m行,每行输入两个正整数u和v,代表城市u和城市v有一条道路连接。
1≤n,m≤10^5
u≠v
输出描述
输出两个整数,第一个整数代表占领的城市编号,第二个整数代表占领后的收益。
请保证收益的最大化。如果有多种方案收益最大,请输出占领编号最小的城市。
输入示例
5 5 01010 1 2 1 3 1 4 4 5 1 5
输出示例
1 3
说明示例
占领 1 号城市后,总收益为 3。
1 号城市和 2 号城市经商,1 号城市和 4 号城市经商,2 号城市和 4 号城市经商。
解题思路-并查集
不要求直接联通,所以每个连通块对答案的贡献是固定的,如果连通块内有 n 个点,那么答案就是 n*(n-1)/2 ,所以我们可以用并查集维护出所有的连通块,然后维护出初始的答案,然后枚举剩下的所有为 0 的点变成 1 以后的情况,他会连接所有的相邻的 1 的连通块。
将原本为0的点变成1,收益计算方法:
逐个查看与节点i相连的所有状态为1的节点,去掉这些状态为1的节点在原来的组合数中贡献的组合数。然后更新联通块数量,使用新的连通块数量计算收益。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,sum,ansid,ansmoney,f[N],w[N];
vector<int> g[N];
bool vis[N];
int find(int x){
if(x!=f[x]) f[x]=find(f[x]);
return f[x];
}
void merge(int x,int y){
int fx=find(x),fy=find(y);
//合并的同时更新节点数量
if(fx!=fy){
f[fx]=fy;
w[fy]+=w[fx];
}
}
int main() {
cin>>n>>m;
for(int i=1;i<=n;i++){
f[i]=i;
w[i]=1;
}
string s;
cin>>s;
//为了与城市序号对应
s=" "+s;
//初始化建图
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
if(s[u]=='1'&&s[v]=='1'){
merge(u,v);
}
}
//计算初始化收益
for(int i=1;i<=n;i++){
if(s[i]=='1'){
int fa=find(i);
if(!vis[fa]){
vis[fa]=1;
sum+=w[fa]*(w[fa]-1)/2;
}
}
}
//遍历每个0点
for(int i=1;i<=n;i++){
if(s[i]=='0'){
map<int,int> mp;//记录是否计算过
//遍历该点邻接的点
int tempsum=sum,num=1;
for(auto x:g[i]){
//如果为1,那么要特殊更新
if(s[x]=='1'){
int fx=find(x);
if(mp[fx]) continue;
mp[fx]=1;
//更新一下
tempsum-=w[fx]*(w[fx]-1)/2;
num+=w[fx]; //更新连接块内数量
}
}
//更新收益
tempsum+=num*(num-1)/2;
if(tempsum>ansmoney){
//更新一下
ansid=i;
ansmoney=tempsum;
}
}
}
cout<<ansid<<" "<<ansmoney;
return 0;
}