总共4道算法题,全部AC,题目属于一般难度,没有涉及acm相关知识。
第一次为自己而做的笔试,给了头条,结果还算满意吧。
这里先申明一下,做的过程中我就直接在网页上写的代码,所以本地没有存储最后通过的代码,以下我写的代码都是我凭记忆写的(应该也不会出错,毕竟刚做,而且也不难),这也算一个教训,下次一定会记录下来
1. 硬币问题
Z国的货币系统包含面值1、4、16、64元共计4种硬币,以及面值1024元的纸币。现在小Y使用1024元的纸币购买了一件价值为N(0<N<=1024)的商品,请问最少他会收到多少硬币?
输入描述:
一行,包含一个整数N
输出描述:
一行,包含一个数,表示最少收到的硬币数
示例1:
输入:200
输出:17
解释:824 = 64x12 + 16x3 + 4x2, 12 + 3 + 2 = 17
思路分析:
第一眼瞟过去以为是一个标准的零钱凑整问题,但是立马发现硬币的面值为定值且呈倍数关系
也就是能用大面值的情况,绝对不可能去使用小面值,故贪心可解。1
2
3
4
5
6
7n = int(input())
target = 1024 - n
res = 0
for val in [64,16,4,1]:
res += target // val
target %= val
print(res)
2. 校对程序
实现一个单词校对程序,实现以下几个功能:
- 如果有三个同样的字母连在一起,则需要去掉一个,如’helllo’ -> ‘hello’
- 如果有两对同样的字母(AABB型)连在一起,去掉第二对的一个字母,如’helloo’ -> ‘hello’
- 上面的规则都必须优先从左到右匹配,如’AABBCC’,要先处理第一个’AABB’,结果为’AABCC’
输入描述:
第一行包含一个数字n,表示本次用例包括多少个待校验的字符串
之后n行,每行为一个待校验的字符串。
输出描述:
n行,每行包括一个被修复后的字符串
示例1:
输入:
2
helloo
wooooooooow
输出:
hello
woow
思路分析:
题意其实还是比较明确的,对于当前遍历的字符v
,只要分别判断他与前一个字符p
,前前一个字符pp
,前前前一个字符ppp
之间的关系即可,若满足两种规则中的任意一种,则删去v字符。
这里我使用队列实现,我觉着这样写起来会更清晰一点(也可以使用指针)
1 | import collections |
3. 奖品数量
有n个人参加编程比赛,比赛结束后每个人都有一个分数
现在所有人排成一个圈(第1个人和第n个人相邻)领取奖品,要求满足:
- 如果一个人比他相邻的人的分数高,那么他获得的奖品应该要多余相邻的人
- 每个人至少需要得到一个奖品
输入描述:
第一行是一个整数t,表示测试样例的个数
每个测试样例的第一行是一个正整数n,表示参加比赛的人数(0 < n < 100000)
第二行是n个整数a[i],表示每个人的分数(0 < a[i] < 100000)
输出描述:
对每个测试样例,输出应该准备的最少奖品数
示例1
输入:
2
2
1 2
4
1 2 3 3
输出:
3
8
思路分析:
这道题和leetcode上的第135题candy几乎一模一样,只不过candy中是一列,而这里是一个环。
因为去年做candy的时候代码写的很长很乱,虽然通过但思路很不清晰,看了discuss发现原来两个循环就解决了,当时惊呆了所以印象特别深。
这道题也可以用candy的思路来做,不过需要多处理一下首尾的位置
1 | t = int(input()) |
4. 绳子裁剪
有N根绳子,第i根绳子的长度为l[i],现在需要M根等长的绳子。
你可以对这N根绳子进行任意裁剪(不能拼接),请你计算出这M根绳子最长的长度
输入描述:
第一行包括两个整数N,M,含义如题所述(1 <= N,M <= 100000)
第二行包含N个整数,分别对应N根绳子的长度(0 < l[i] < 10^9)
输出描述:
一个数字,表示裁剪后最长的长度,保留两位小数
示例1
输入:
3 4
3 5 4
输出:
2.50
解释: 第一根和第三根绳子分别裁剪出一根2.50长度的绳子,第二根绳子刚好可以裁剪出两根2.50的长度绳子,刚好4根。
思路分析:
前些天才讲了二分法系列的详解,这种程度的题目根本不足以作为最后一道题啊
重点:找到一个数,这个数需要满足一定的条件
,看到这种模式的题目马上要想到二分
三步法:
- 定区间。这里使用绳子的长度区间即可(lo,hi = 0, 10^9)
- 确定判断条件。对于我们找到的mid,我们需要判断
如果剪成mid长度的绳子,计算最多能剪出来的绳子数量cnt,如果cnt >= m,说明此时当前的长度还小了,可以尝试去找更大的长度(lo=mid),反之则找更小的长度(hi=mid)
- 循环外返回结果。因为结果可能是小数,那么只要lo,hi出循环的时候足够接近即可(hi - lo < 10^-6)
1 | n,m = map(int, input().split()) |
这个代码多漂亮啊,嘻嘻!