大家好,我是吴师兄。
提前批开始啦!
早点练习,准备好秋招吧。
今天分享的是科大讯飞的笔试题,拿下它!!!
1、小U的树形权值调整
小U在处理一棵特殊的树,树中每个节点都有一个独特的权值。目标是通过最少的权值交换,使得每个节点的权值与其编号相匹配。已知权值组成了一个排列,所以理论上是可行的。
输入
首先,输入一个整数
,表示树的节点数量。
其次,输入一行
个整数,表示每个节点的权值
,保证权值是互不相同的排列。
接下来的
行,每行输入两个整数
,表示树的节点之间的连线。
输出
输出一个整数,表明需要的最小交换次数。
样例
输入:
4
2 1 4 3
1 2
2 3
2 4
输出:
2
题目解析
题目要求我们通过最少的交换次数,使得树中每个节点的权值与其编号相匹配。给定的权值是一个排列,这意味着每个权值都唯一且都在 1 到 n 的范围内。
1、
理解问题本质
:题目给了我们一个树结构,并且每个节点有一个权值。目标是通过交换使得每个节点的权值等于它的编号。因为权值是一个排列,所以每个节点的权值都唯一。
2、
转换为排列问题
:其实这个问题可以简化为排列中环的求解。我们可以将问题简化为:给定一个排列,找出排列中所有的环,然后计算最少的交换次数。
3、
环的交换次数
:对于一个环来说,若环的长度为 k,那么需要 k-1 次交换就能使得所有元素回到正确的位置。
具体实现步骤
1、
输入解析
:首先读取输入的节点数 n 和权值排列。
2、
处理权值排列
:为了方便处理,我们将权值排列调整为从 1 开始的下标,即在原数组前加一个 0。
3、
标记访问过的节点
:使用一个布尔数组 vis 来标记节点是否已经访问过。
4、
寻找环并计算交换次数
:遍历所有节点,寻找没有访问过的节点,然后通过遍历找到一个环,计算环的长度并累加到最终结果中。
代码
# 读取节点数量
n = int(input())
# 读取节点的权值排列,并在前面加0以使下标从1开始
a = [0] + list(map(int, input().split()))
# 初始化一个访问标记数组,记录节点是否被访问过
vis = [False for _ in range(n + 1)]
# 初始化交换次数为0
ans = 0
# 遍历每个节点
for k in range(1, n + 1):
# 如果节点k没有被访问过
if not vis[k]:
# 从节点k开始遍历
i = k
# 初始化环的节点数
cnt = 0
# 遍历环
while not vis[i]:
# 标记节点i为已访问
vis[i] = True
# 环的节点数加1
cnt += 1
# 转到下一个节点
i = a[i]
# 对于一个环,需要的交换次数是环的长度减1
ans += cnt - 1
# 输出最少的交换次数
print(ans)
2、北京时间转世界协调时间
东八区(UTC/GMT+08:00)是一个时区,位于东经112.5度至127.5度之间。当全球标准时间为00:00时,东八区的时间为08:00。本题目要求将北京时间(东八区时间)转换为世界协调时间(UTC)。
输入
每个测试文件包含多组数据。首行输入一个整数表示数据组数。
每组数据为一行,格式为"小时:分钟"表示的北京时间(24小时制)。
输出
对每组数据,输出转换后的世界协调时间,格式为两位数小时和两位数分钟。
样例
输入:
2
8:30
00:00
输出:
00:30
16:00
题目解析
题目要求我们将输入的北京时间(东八区时间)转换为世界协调时间(UTC)。北京时间比UTC时间快8小时,因此需要将北京时间减去8小时得到对应的UTC时间。
1、
读取输入
:首先读取输入的测试数据组数。
2、
处理每组数据
:对于每组数据,将输入的北京时间格式化为小时和分钟,然后将其转换为UTC时间。
3、
格式化输出
:转换后的UTC时间需要格式化为两位数小时和两位数分钟的形式输出。
具体实现步骤
1、
计算时差
:北京时间减去8小时,如果减去8小时后小时数小于0,则需要加上24小时使其成为正数(即转到前一天)。
2、
处理分钟数
:分钟数无需变化,直接保留原始分钟数。
3、
格式化时间
:将小时和分钟格式化为两位数输出。
代码