[解题报告] CSDN竞赛第23期
创始人
2024-05-11 23:22:04

CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/37

1. 排查网络故障

题目

A地跟B地的网络中间有n个节点(不包括A地和B地),相邻的两个节点是通过网线连接。正常的情况下,A地和B地是可以连通的,有一天,A地和B地突然不连通了,已知只有一段网线出问题(两个相邻的节点)小明需要排查哪段网线出问题。他的排查步骤是:
1。 选择某个中间节点
2。 在这个节点上判断跟A地B地是否连通,用来判断那一边出问题

请问小明最少要排查多少次,才能保证一定可以找到故障网线

输入描述:

一个正整数 n (n <= 10^18),表示A地和B地之间的节点数

输出描述:

输出一个数字,代表保证一定可以找到故障网线的前提下,小明最少要排查多少次

输入样例:

2

输出样例:

2

解题报告

模拟,答案为 ⌈log2(n+1)⌉\lceil log_2(n + 1) \rceil⌈log2​(n+1)⌉

class Solution:def __init__(self) -> None:passdef solution(self, n):if n < 2:return nimport mathn += 1result = int(math.log(n))while 2**result < n:result += 1return resultif __name__ == "__main__":n = int(input().strip())sol = Solution()result = sol.solution(n)print(result)

2. 零钱兑换

题目

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币张数。 如果无解,请返回-1. 数据范围:数组大小满足 0 <= n <=10000 , 数组中每个数字都满足 0 < val <=10000,0 <= aim <=100000 要求:时间复杂度 O(n×aim) ,空间复杂度 O(aim)。

输入描述:

输入包括两行,第一行两个整数n(0<=n<=1000)代表数组长度和aim(0<=aim<=5000),
第二行n个不重复的正整数,代表arr(1 <= arri <=10^9)

输出描述:

输出一个整数,表示组成aim的最小货币数,无解时输出-1.

输入样例:

[5,2,3],20

输出样例:

4

解题报告

动态规划,设 f[i] 为组成 i 的最少货币数,初始时 f[i] = oo,则 f[i] = min{f[i - j] + 1}, 其中 j 遍历 arr 中每个值

若 f[aim] > oo 则答案为 -1 否则为 f[aim]

class Solution:def __init__(self) -> None:passdef solution(self, str1):arr, aim = eval(str1)f = [aim + 1] * (aim + 1)f[0] = 0for i in range(1, aim + 1):for j in arr:if j <= i:f[i] = min(f[i], f[i - j] + 1)if f[aim] > aim:return -1return f[aim]if __name__ == "__main__":str1 = input().strip()sol = Solution()result = sol.solution(str1)print(result)

3. 清理磁盘空间

题目

小明电脑空间满了,决定清空间。为了简化问题,小明列了他个人文件夹(/data)中所有末级文件路径和大小,挑选出总大小为 m 的删除方案,求所有删除方案中,删除操作次数最小是多少。

一次删除操作:删除文件或者删除文件夹。如果删除文件夹,那么该文件夹包含的文件都将被删除。
文件夹的大小:文件夹中所有末级文件大小之和

输入描述:

第一行输入 n (n <= 1000)和 m(m <= 1000),表示文件数量,和需要删除的大小

接下去有 n 行,每一行都是一个文件绝对路径(路径长度小于 100),和这个文件的大小(小于 1000)

输出描述:

输出所有删除方案中,删除操作次数最小是多少。如果找不到恰好删除的大小为 m 的方案,则打印 -1

输入样例:

6 10
/data/movie/a.mp4 5
/data/movie/b.mp4 3
/data/movie/c.mp4 2
/data/movie/d.mp4 4
/data/picture/a.jpg 4
/data/picture/b.jpg 1

输出样例:

2

解题报告

动态规划,把所有文件排序,设第 i 个文件名和大小分别为 x, y

设 f[i][j] 为删除前 i 个文件,总大小为 j 时的最少操作数,初始时 f[i][j] = oo,f[0][0] = 0

则 f[i][j] = min{f[i - 1][j], f[i - 1][j - y] + 1},其中 1 <= j <= m

维护上一次的文件夹名称及编号 k 和文件夹总大小 yy,当 x 的文件夹名称与上一次不同时,则 f[i][j] = min{f[i - 1][j], f[i - 1][j - y] + 1, f[k][j - yy] + 1}

若 f[n][m] > oo 则答案为 -1 否则为 f[n][m]

class Solution:def __init__(self) -> None:passdef solution(self, n, m, vector):if m == 0:return 0if n == 0:return -1oo = n * 2f = [[oo for j in range(m + 1)] for i in range(n + 1)]vector = sorted(vector)zz = vector[0][0].split('/')[2]s = 0j = 0f[0][0] = 0for k, (x, y) in enumerate(vector):y = int(y)for i in range(m):f[k + 1][i] = min(f[k + 1][i], f[k][i])if f[k][i] < oo and i + y <= m:f[k + 1][i + y] = min(f[k + 1][i + y], f[k][i] + 1)z = x.split('/')[2]if z != zz:for i in range(m):if f[j][i] < oo and i + s <= m:f[k + 1][i + s] = min(f[k + 1][i + s], f[j][i] + 1)s = yzz = zj = kelse:s += yfor i in range(m):if f[j][i] < oo and i + s <= m:f[k + 1][i + s] = min(f[k + 1][i + s], f[j][i] + 1)ans = min([f[k][m] for k in range(n + 1)])if ans < oo:return ansreturn -1if __name__ == "__main__":arr_temp = [int(item) for item in input().strip().split()]n = int(arr_temp[0])m = int(arr_temp[1])vector = []for i in range(n):vector.append([item for item in input().strip().split()])sol = Solution()result = sol.solution(n, m, vector)print(result)

4. 交际圈

题目

小明参加了个大型聚会。聚会上有n个人参加,我们将他们编号为1…n,有些人已经互相认识了,有些人还不认识。聚会开始后,假设A跟B认识,A会给所有他认识的人介绍B,原先跟A认识,但不认识B的人,都会在此时,跟B互相认识。当所有人都把自己认识的人介绍一遍后,此时n个人就会形成k个交际圈,同一个交际圈中,两两互相认识,不同的交际圈之间,互相不认识
问题:当所有人都把自己认识的人介绍一遍后,形成了多少个交际圈

输入描述:

第1行包含两个数字n(n <= 100000), m(m <= 100000),n表示参加聚会的人数,m表示聚会前,有多少对人已经互相认识了
第2行到第m+1行,每一行包含两个数字,a和b(a != b, 1 <= a, b <= n),代表的是聚会前,a和b已经互相认识

输出描述:

输出一个数字,表示形成的交际圈的个数

输入样例:

3 3
1 2
1 3
2 3

输出样例:

1

解题报告

图论。用并查集统计有多少个连通块即可

class Solution:def __init__(self) -> None:passdef getf(self, x):if self.f[x] != x:self.f[x] = self.getf(self.f[x])return self.f[x]def solution(self, n, m, vector):self.f = [i for i in range(n + 1)]v = set()for x, y in vector:x = self.getf(self.f[x])y = self.getf(self.f[y])self.f[x] = yfor i in range(1, n + 1):self.f[i] = self.getf(i)return len(set(self.f[1:]))if __name__ == "__main__":arr_temp = [int(item) for item in input().strip().split()]n = int(arr_temp[0])m = int(arr_temp[1])vector = []for i in range(m):vector.append([int(item) for item in input().strip().split()])sol = Solution()result = sol.solution(n, m, vector)print(result)

相关内容

热门资讯

最新或2023(历届)第三届世... 由国家网信办、科技部、工信部、浙江省政府共同主办的第三届世界互联网大会·互联网之光博览会将于最新或2...
最新或2023(历届)最新无故... 第一篇:无故旷工检讨书  尊敬的领导:  您好~谢谢您能在百忙之中抽空看我写的检讨书!  *月*日,...
汉中之战曹操为何会输?因为他错... 今天趣历史小编为大家带来了一篇关于曹操的文章,欢迎阅读哦~汉献帝被曹操控制后,一直想找机会翻身,可惜...
中秋节招待会上的祝酒词 中秋节... 中秋节招待会上的祝酒词 尊敬的吕梁市政协刘本旺主席,尊敬的柳林县常委贺柱才部长 各位领导...
在迎新茶话会上的发言 迎新茶话... 在迎新茶话会上的发言各位领导、老师们:大家好。很荣幸能有这个会来代表普通教师发言。我在想为什么让我来...