6.23天津大学夏令营初筛机试
- 题目设置:一共5道题,只有10%~30%的样例。
- 考试时间:9:30~11:30,共2h。
1 题目A:整数化
1.1 题目描述
小Z在处理二维坐标点上的数据,受到性能限制,他希望把所有的点对应到距离它最近的整数点(横纵坐标均为整数)上, 请你帮他完成这个程序。
如果一个点有多个距离它最近的点,取横纵坐标更小的那个点。如(1, 1.5)将对应到(1, 1),(-1, -1.5)将对应到(-1, -2)。
1.2 输入
多组样例输入,第一-行输入一个整数T表示样例数。
对于每个样例,包含两个数表示需要整型化的点。
1.3 输出
对于每组样例,输出一行包含两个整数的坐标,用空格分割。
1.4 样例输入
3
1 1.5
2 3.2
-1 -2
1.5 样例输出
1 1
2 3
-1 -2
1.6 解题思路
一开始直接使用了取整int()
,但是当输入为负数的时候,例如-1.6取整为-1,但是题意要求是-2,所以应该判断一下小数部分和0.5的关系,分类讨论。
最终这个对于部分数据AC了,但是不知道剩下的数据怎么样。
1 |
|
2 题目B:多项评价指标
2.1 题目描述
Dice系数和IoU均为衡量两个集合相似度的重要度量,是图像分割领域的最常用的评价指标,小Z希望写一个程序完成两个指标的转化。
Dice系数计算方式:
$$
Dice =\frac{T P}{T P+F P+F N}
$$
IoU计算公式:
$$
I o U=\frac{T P+T P}{T P+T P+F P+F N}
$$
二者转化公式:
$$
Dice =\frac{2 \times I o U}{I o U+1}
$$
2.2 输入
多组样例输入,第一行输入一个整数T表示样例数。
对于每个样例,输入一行,包括度量名称及度量值,中间用空格隔开,其中指标名称只能为”dice”或”iou”,例如”dice 0.45”, “iou 0.80”。
输入的IoU
和Dice
均在[0, 1]范围内。
2.3 输出
对于每组样例,输出一个数字表示转化为另一种度量的结果,输出四舍五入保留两位小数。
2.4 样例输入
3
dice 0.4
iou 0.8
dice 0.9
2.5 样例输出
0.25
0.89
0.82
2.6 解题思路
这题不需要使用任何算法,根据题目给出的公式直接计算即可,需要转换得到IoU
的计算公式,如下:
$$
IoU =\frac{Dice }{2-Dice }
$$
1 |
|
3 题目C:跳着数数
3.1 题目描述
小Z不喜欢0~9中较大的数字,他想知道如果去掉所有包含大数字的数之后[1, n]区间内,还剩多少个数。
例如,小Z不喜欢三个7,8,9数字,将所有任意位存在这三个数字的数去掉后,[1, 12]中只剩下了[1, 2, 3, 4, 5, 6,10, 11, 12]这9个数。
注意,9, 19, 190都包含9数字9,在计数时都需要删去。
3.2 输入
多组样例输入,第一行输入一个整数T表示样例数。
对于每个样例,包含两个数字n k,n表示需要在[1, n]内进行统计,k表示小Z不喜欢的数字为[k, 9]。
其中$n \leq 10^{18}$,$1 \leq k \leq 9$。
3.3 输出
对于每组样例,输出一个数字表示删除不喜欢的数后剩余数字的数量。
3.4 样例输入
2
12 7
100 5
3.5 样例输出
9
25
3.6 解题思路
看到n的范围比较大,所以要先用long long存储,然后如果直接枚举,肯定会超时,这里可以首先分析n是几位数,如果是之前的话可能要写一个函数判断,但是之前学了一个技巧,先将其转化字符串,然后判断这个字符串的长度,就是n的位数,记为num
。
然后分析$ 1 \sim num - 1$位数中有多少个数满足要求:由于$[k, 9]$之间的数字不能出现,因此每一位只有$[0,k-1]$个选法,注意最高位不能为0,所以最高位只有k-1中选法,其他有k中选法,这也就是get函数的作用。
当判断num
位数中,有多少个是小于n的(写到这里的时候突然发现考试虽然过了部分数据,但是这里应该是不对的),比如n是22,k为9,此时可以取18,但是下面的写法是没有计算18的,所以错误。
1 |
|
下面的做法是正确的:
1 | LL calu() |
4 题目D:掩码匹配
4.1 题目描述
数字在计算机中是以二进制存储的,小Z在监控程序运行状态。他想知道给定一个掩码,一段内存中有多少个数可以匹配该掩码。
匹配定义:待匹配数为a,掩码为b,若b的二进制表示中所有的1,在a的二进制表示的相对应位置也为1,则称a可以匹配掩码b。
例如,1为掩码,其二进制表示为”1”,则1(1),3(11),5(101),7(111),……均可匹配该掩码,括号内为该数字对应二进制表示。
又例如,13的二进制为”1101”,如果掩码为12,12的二进制为”1100”,掩码12可以匹配数字13。同时该掩码也可以匹配数字15(1111)。
为了简化问题,小Z所有的掩码保证二进制下1的个数不超过2个。
4.2 输入
第一行包含一个整数n,表示观测的内存长度,编号从1到n。
第二行包含n个整数表示内存中存储的数。
第三行包含一个整数q表示询问数量。
接下来q行每行包含三个整数s t m,表示从位置s到位置t,掩码为m。
数据范围:
- $1 \leq n \leq 20000$
- $1 \leq q \leq 100000$
- $m > 0$且保证二进制下至多两位为1
- 内存中储存的数字范围为$[1, 10^8]$
4.3 输出
对于每次询问,输出一个整数表示从到s到t(包含起点和终点),可有多少数字可以匹配掩码m。
4.4 样例输入
8
1 2 3 4 5 6 7 8
3
1 8 3
1 8 1
3 8 6
4.5 样例输出
2
4
2
对于询问1,区间[1, 8]内3和7可以匹配掩码3。
对于询问2,区间[1, 8]内[1, 3, 5, 7]可以匹配掩码1。
对于询问3,区间[3, 8]内6和7可以匹配掩码6。
4.6 解题思路
当时做的时候直接使用的暴力,样例可以通过,但是剩下的测试数据中肯定会超时,所以最后又想了一个优化,但是没有时间了。
可以将输入的数据进行预处理,类似桶排序的思想,预处理出来一个数的二进制中哪些位为1,然后将这些数保存在对应的桶中,之后直接查询即可。
1 |
|
5 题目E:更短的最短路
5.1 题目描述
小Z在处理一个特殊的最短路径问题,在无向图中有部分边在最初始时是上锁没法通过的,当他拿到位于节点k的钥匙后,这些边就可以通过了。
通过一条边的花费为边权值,他想知道从节点1走到节点n的最小花费是多少。
5.2 输入
多组样例输入,第一行输入一个整数T表示样例数。
对于每个样例,第一行包含两个整数n,m,k, 图一共n个节点m条边,节点编号从
到1到n,钥匙在节点k。
接下来行每行包含四个整数,s t w v表示有一条从s到t的边,权重为w,如果v为0则表示不需要钥匙就可以通行,如果是1则表示该边需要拿到钥匙后才能通行。
5.3 输出
对于每组样例,输出一个整数表示从1到n的最短路,如果不能到达,则输出-1。
5.4 样例输入
2
3 3 1
1 2 1 0
2 3 1 0
1 3 5 0
4 4 3
1 3 1 0
1 2 1 0
2 4 1 1
3 4 100 0
5.5 样例输出
2
4
5.6 解题思路
需要思考的问题是这个与以往的最短路问题有什么不同?有一个钥匙的限制。
先判断是否可以只走不需要钥匙的边到达终点
- 可以:需要先计算获得钥匙,然后再从钥匙所在点走到终点的代价的最小值
- 不可以:需要先计算获得钥匙,然后再从钥匙所在点走到终点的代价
综上:最小代价就是不需要钥匙和需要钥匙的最小代价。
1 |
|
6 总结
已经参加了好几个机试了,感觉最重要的是在考试的时候保持思路的清晰,一定要考虑好边界情况,有的考试其实并不是一定考核你的算法能力,题目并不难,但是一定要考虑全面。
这次感觉第3题有些可惜,其次第4题明明可以优化,但是没时间了,花费挺多时间在第5题上了。
另外一定要背熟模板,像这次的迪杰斯特拉算法其实就是忘了一部分,考场上现写的,所以还是要加强模板的掌握,其次写代码的时候一定要保证写一个就对一个,不要指着debug找错误。
下一步需要加强的地方:
- 加强记忆模板
- 练习的时候尽量不看测试用例,自己先想哪里错了
- 将题目和自己做过的题进行类比,看有哪些相同的地方
- 考虑问题要全面,做题的时候就要像可能会有哪些临界情况