【算法刷题-题解】2024_09_10_Oppo_2024_AI_C卷

1.执行以下程序,输出结果为(False)
l1 = [1,2]
l2 = [3,4]
print(id(l1) == id(l1.extend(l2)))
官方解析:id()函数可以返回对象的内存地址,由于l1.extend(l2)会在原l1的基础上合并l2,也就是说,使用l1.extend(l2)后,l1的值变为[1,2,3,4],
且地址不会发生改变,所以很容易误认为输出结果为True,从而错选B选项。实际上,l1.extend(l2)是没有返回值的,
或者说,返回值为None,因此本题实际上是判断id(l1) == id(None)的值,显然结果为False,故正确答案为A选项。


5.下列关于辅助索引说法错误的是(B)
A.如果一条关系可以有不止一条包含相同搜索码值的记录,则该搜索码称为非唯一性搜索码
B.辅助索引可以是稀疏的,且每个搜索码值可以多个索引项
C.辅助索引只存储部分搜索码值,则具有中间搜索码值的记录可能存在于文件中的任何位置
D.非唯一性搜索码上的辅助索引中的指针不会直接指向记录
官方解析:
非唯一性搜索码就是指如果一种关系可以有不止一条包含相同搜索码值的记录也就是两条或者多条记录对于索引属性可以具有相同的值,故A排除;
而辅助索引必须是稠密的,对每个搜索码值都有一个索引项,并且对文件中的每条记录都有一个指针,而聚集索引可以是稀疏的存储部分的搜索码值,故B错误;
同时如果辅助索引值存储部分搜索码值,则具有中间搜索码值的记录可能存在于文件中的任何位置,通常是扫描整个文件去发现这些记录,故C排除;
在非唯一性搜索码上实现辅助索引,其指针不会直接指向记录,而是指向一个桶,桶中包含指向文件的指针,故D排除,因此正确选项为B。


8.下列关于 XGBoost 的说法,错误的是(A)
A.
XGBoost 支持单颗树粒度的并行
B
XGBoost 支持特征抽样
C
XGBoost 在代价函数里加入了正则项
D
XGBoost 支持对缺失值的自动处理
官方解析:XGBoost 在特征粒度上支持并行,A 说法错误;XGBoost 支持列抽样,即特征抽样,B 说法正确;
XGBoost 在代价函数里加入了正则项用于控制模型的复杂度,C 说法正确;XGBoost 对于特征的值有缺失的样本,可以自动学习出它的分裂方向,D 说法正确。因此选择 A 选项



9.
r(AT) = 3,若齐次方程Ax=0有基础解系k1,k2,则下列哪个说法满足题意(D)

A
A为3×3矩阵
B
A为4×4矩阵
C
A为5×4矩阵
D
A为5×5矩阵
官方解析:首先,r(AT) = r(A) = 3。又因为齐次方程Ax=0的基础解系中,解向量的个数为n-r(A)2,故n≥5。A为m×n矩阵,因此D选项满足题意。



10.
下列关于半监督学习的说法,正确的有(B)
A
直推学习假定训练数据集中的未标记数据并非待预测数据
B
半监督学习的训练集同时包含有标记样本数据和未标记样本数据
C
纯半监督学习假定学习过程中的未标记数据就是待预测数据
D
其余选项均正确

官方解析:半监督学习可以进一步划分为纯半监督学习和直推学习,
其中,纯半监督学习假定训练数据集中的未标记数据并非待预测数据,直推学习假定学习过程中的未标记数据就是待预测数据,因此 A、C 选项错误;
让学习过程不依赖外界的咨询交互,自动利用未标记样本所包含的分布信息的方法便是半监督学习,即训练集同时包含有标记样本数据和未标记样本数据,
B 选项正确。


11.
关于InnoDB存储引擎,以下说法正确的是(A)
A
InnoDB存储引擎的逻辑结构最高层次是表空间,所有的数据都放在表空间中
B
在Inn
oDB存储引擎中,磁盘管理的最小逻辑单元是行
C
在InnoDB存储引擎中,页大小可以通过参数 innodb_page_size更改,默认大小为4KB
D
在InnoDB存储引擎中,区是由页组成的连续空间,其大小是2MB

官方解析:
磁盘管理的最小逻辑单元是页,默认大小是16KB,每个区的大小都是1MB,每个区都包含64个连续的页。



13.
C++11 中有如下 Employee 类代码,则下面选项中不能正确创建 Employee 对象的是(A)

class Employee {
private:
    std::string name;
    double salary;
public:
    Employee(const std::string &name, double salary) {
        /*代码省略*/
    }
};
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选项错误,调用无参的默认构造函数,因定义了构造函数因此默认构造函数不存在,B选项显示的调用构造函数,
C选项是使用new加构造函数的方式初始化指针对象,D选项是C++11的列表初始化方式。



15.
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


17.
判断两个单链表是否相交的最优操作是(B)
A
遍历第一个链表的每个结点,依次与第二个链表的每个结点比较,如果存在相同的结点,则两个链表相交
B
遍历第一个链表,将每个结点的指针保存到一个哈希表中,然后遍历第二个链表,检查每个结点是否在哈希表中,如果存在,则两个链表相交
C
遍历第一个链表,将最后一个结点的指针指向第二个链表的头节点,然后判断第二个链表是否存在环,如果存在环,则两个链表相交
D
遍历第一个链表,将最后一个结点的指针指向第二个链表的头节点,然后判断第一个链表是否存在环,如果存在环,则两个链表相交

官方解析:要判断两个单链表是否相交,可以使用哈希表的方法。首先遍历第一个链表,将每个结点的指针保存到一个哈希表中
。然后遍历第二个链表,对于每个结点,检查其是否在哈希表中。如果存在,则表示两个链表相交。
选项A是一种暴力解法,需要遍历两个链表的所有结点进行比较,时间复杂度较高。
选项C和选项D是通过改变链表的结构来判断两个链表是否相交,但会改变原有的链表结构,不符合实际应用场景。
因此,选项B是较优解,使用哈希表来保存第一个链表的结点,然后遍历第二个链表进行比较,判断两个链表是否相交。


18.
对数组a=[6, 2, 9, 4, 1, 7]采用快速排序的方法,以第一个元素为基准,从小到大排序,则第一次得到的划分结果是( C)
A
[2, 6, 9, 4, 1, 7]
B
[6, 2, 9, 4, 1, 7]
C
[1, 2, 4, 6, 9, 7]
D
[4, 2, 1, 6, 9, 7]

官方解析:快速排序的划分过程是通过选择一个基准元素,将数组分为两个部分,小于基准的放在左边,大于基准的放在右边。
以第一个元素6为基准,第一次划分后,小于6的元素为[2, 4, 1],大于6的元素为[9, 7],所以划分结果为[1, 2, 4, 6, 9, 7],对应选项C。

  Input In [1]
    1.执行以下程序,输出结果为(False)
            ^
SyntaxError: invalid character ',' (U+FF0C)
21.小欧逛商店:有n个物品,第i个物品体积为a^i,价值为b^i。小欧背包容量为x,每次看到能装进去的就装进去,装不进去就跳过.共能买多少价值的物品?
    输入描述:第一行输入两个正整数n,x,代表物品数量和背包容量。
    接下来的n行,每行输入两个正整数a_i和b_i,代表每个物品的体积和价值。
    0<n<10^5
    输入例子:
    3 5
    4 3
    2 5
    1 3
    输出例子:
    6
    例子说明:
    先买第一个物品,价值为 3。
    遇到第二个物品时,此时剩余容量为 1,无法购买。
    然后买第三个物品,价值为 3
n,v = input().split(' ')
v = int(v)
m_num = 0
v_num = 0
for i in range(int(n)):
    v1,m1 = input().split(' ')
    v1=int(v1)
    m1=int(m1)
    if v-v_num >= v1:
        v_num = v_num + v1
        m_num = m_num + m1
print(m_num)

3 5
4 3
2 5
1 3
6
n,v = input().split(' ')
n = int(n)
v = int(v)
v_c = 0
p_c = 0
for i in range(n):
    v1,p1 = input().split(' ')
    v1 =int(v1)
    p1 = int(p1)
    if v - v_c >= v1:
        v_c = v_c + v1
        p_c = p_c + p1
    
print(p_c)
3 5
4 3
2 5
1 3
6
22.小欧的字符串构造
小欧有一个字符串 s ,她想构造一个长度为 k 的字符串 t ,使得 s+t 或 t+s 拼成的字符串是回文串。

如果可以构造,则输出 t ,若无法构造,请输出 -1。
输入描述:
    第一行输入一个长度不超过10^5的字符串s
    第二行输入一个整数k
示例:
输入:
abc
3
输出:
cba
s = input()
k = int(input())
n = len(s)

if k >= n:
    print('a' * (k-n) + s[::-1])
else:
    front = s[n-k:][::-1] + s
    back = s + s[:k][::-1]
    mid = int((n+k)/2)
    if front[:mid] == front[mid+(n+k)%2:][::-1]:
        print(s[n-k:][::-1])
    elif back[:mid] == back[mid+(n+k)%2:][::-1]:
        print(s[:k][::-1])
    else:
        print(-1)
    
abc
3
cba
s = input()
k = input()
n = len(s)
k = int(k)

if k>=n:
    print( 'a'*(k-n)+s[::-1])
else:
    front = s[n-k:][::-1] + s
    back = s + s[:k][::-1]
#     print(front)
#     print(back)
    mid = int((k+n)/2)
    if front[:mid] ==front[mid+(k+n)%2:][::-1]:
        print(s[n-k:][::-1]) 
    elif back[:mid] ==back[mid+(k+n)%2:][::-1]:
        print(s[:k][::-1])
    else:
        print(-1)
    
aaabc
2
cb
23.小欧皇
小欧正在扮演一个中世纪的皇帝。地图上有
n个城市,其中有m条道路,每条道路连接了两个城市。
小欧占领了其中一些城市。如果两个城市可以通过若干条道路互相到达,且这些道路经过的城市都是小欧占领的,
那么这两个城市之间就可以通过经商获得收益1
。请注意,每两个城市之间的收益只会被计算一次。
现在,小欧准备占领一个未被占领的城市,使得总收益最大化。你能帮帮她吗?
输入描述:
    第一行输入两个正整数n和m,代表城市数量和道路数量
    第二行输入一个长度为m的01串,第i个字符为‘0’代表小欧未占领城市,‘1’代表小欧占领了城市
    接下来的m行,每行输入两个正整数u和v,代表u和v有一条道路连接

输出描述:
    输出两个整数:第一个整数代表占领的城市编号,第二个整数代表占领后的利益
    请保证收益最大化。如果有多种方案收益最大,请输出占领编号最小的城市
示例:
输入:
    5 5
    01010
    1 2
    1 3
    1 4
    4 5
    1 5
输出:
    1 3
  Input In [9]
    小欧正在扮演一个中世纪的皇帝。地图上有
                  ^
SyntaxError: invalid character '。' (U+3002)
from collections import defaultdict

def solve(n, m, occupied, roads):
    # 创建邻接表
    graph = defaultdict(list)
    for u, v in roads:
        graph[u-1].append(v-1)
        graph[v-1].append(u-1)
    
    # 使用并查集来跟踪连通分量
    parent = list(range(n))
    size = [1 if occupied[i] else 0 for i in range(n)]

    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
        return parent[x]

    def union(x, y):
        px, py = find(x), find(y)
        if px != py:
            if size[px] < size[py]:
                px, py = py, px
            parent[py] = px
            size[px] += size[py]

    # 初始化连通分量
    for i in range(n):
        if occupied[i]:
            for j in graph[i]:
                if occupied[j]:
                    union(i, j)

    # 计算当前收益
    current_profit = sum(size[i] * (size[i] - 1) // 2 for i in range(n) if i == find(i) and size[i] > 0)

    max_profit_increase = 0
    best_city = 0

    # 尝试占领每个未占领的城市
    for city in range(n):
        if not occupied[city]:
            connected_components = set()
            total_size = 1  # 包括新占领的城市

            for neighbor in graph[city]:
                if occupied[neighbor]:
                    root = find(neighbor)
                    if root not in connected_components:
                        connected_components.add(root)
                        total_size += size[root]

            new_profit = total_size * (total_size - 1) // 2
            old_profit = sum(size[root] * (size[root] - 1) // 2 for root in connected_components)
            profit_increase = new_profit - old_profit

            if profit_increase > max_profit_increase:
                max_profit_increase = profit_increase
                best_city = city + 1

    return best_city, current_profit + max_profit_increase

# 读取输入
n, m = map(int, input().split())
occupied = [c == '1' for c in input().strip()]
roads = [tuple(map(int, input().split())) for _ in range(m)]

# 解决问题并输出结果
city, profit = solve(n, m, occupied, roads)
print(f"{city} {profit}")
5 5
01010
1 2
1 3
1 4
4 5
1 5
1 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值