第一题:字符串分割-水仙花数(用例通过率:11.1%)
第二题:内存资源分配(用例通过率:95.8%)
第三题:模拟内存分配(用例通过率:15%)
之前在网上也看了很多分享,虽然机考没通过,不过也分享一下遇到的考题。
说明:
1.试题是考后在网上找的原题或比较类似的题。
2.代码是考试时候写的,可能写的有点乱。考试时候只管用例通过率,不讲究格式或有没有冗余代码。
第一题 字符串分割-水仙花数
题目描述
给定非空字符串s,将该字符串分割成一些子串,使每个子串的ASCII码值的和均为水仙花数。
1、若分割不成功,则返回0
2、若分割成功且分割结果不唯一,则返回-1
3、若分割成功且分割结果唯一,则返回分割后子串的数目
输入描述
输入字符串的最大长度为200
输出描述
根据题目描述的情况,返回相应的结果
示例1
输入
abc
输出
0
说明
分割不成功
示例2
输入
f3@d5a8
输出
-1
说明
分割成功但分割结果不唯一,可以分割为两组,一组'f3'和'@d5a8',另外一组'f3@d5'和'a8'
示例3
输入
AXdddF
输出
2
说明
分割成功且分割结果唯一,可以分割成'AX'和'dddF'两个子串
备注
“水仙花数”是指一个三位数,每位上数字的立方和等于该数字本身,如371是'水仙花数',因371=3^3+7^3+1^3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#以下代码用例通过率为:11.1%
s = input()
l = []
tem = []
c = []
for i in s:
l.append(ord(i))
for i in range(len(s)):
for j in range(i,len(s)+1):
if l[i:j] not in tem and len(str(sum(l[i:j]))) == 3:
tem.append(str(sum(l[i:j])))
for i in tem:
if int(i[0])**3+int(i[1])**3+int(i[2])**3 == int(i):
c.append(int(i))
if len(c) == 0:
print(0)
else:
if sum(l) == sum(c):
print(len(c))
else:
print(-1)
说明:本题我在考试的时候理解成只要能分出水仙花数就算分割成功。其实应该是分割的每个子串都是水仙花数才能算分割成功。不过这题在分组上确实也有难点,因为即使子串已经是水仙花数了,再加字符可能仍然是水仙花数。一个字符串可以分割出很多个水仙花数,也存在多个分组。这样应该用到回溯来解此题。
考后结合评论区兰夜的提示和想到力扣93题复原IP地址用到的回溯方法,重新解此题:
首先:咋们以s = "f3@d5a8"为例,利用回溯方法找一下可能的具体分组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1.提取字符及其ASCII码
s = "f3@d5a8"
ls =list(s)
nums = []
for i in s:
nums.append(ord(i))
# 2.列出所有三位数的水仙花数
narcissus_nums = []
for i in range(100,1000):
i = str(i)
if int(i[0])**3+int(i[1])**3+int(i[2])**3 == int(i):
narcissus_nums.append(int(i))
# 3.回溯
def backtrack(ls,nums,stk):
if sum(nums) in narcissus_nums:
stk.append("".join(ls))
res.append(stk[:])
stk.pop()
return
for i in range(1,len(nums)):
if sum(nums[:i]) in narcissus_nums:
stk.append("".join(ls[:i]))
backtrack(ls[i:],nums[i:],stk)
stk.pop()
res = []
backtrack(ls,nums,[])
# 4.输出
print(res)
输出结果:
1
[['f3', '@d5a8'], ['f3@d5', 'a8']]
其次:按输出要求,修改为如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 1.提取字符及其ASCII码
s = input()
ls =list(s)
nums = []
for i in s:
nums.append(ord(i))
# 2.列出所有三位数的水仙花数
narcissus_nums = []
for i in range(100,1000):
i = str(i)
if int(i[0])**3+int(i[1])**3+int(i[2])**3 == int(i):
narcissus_nums.append(int(i))
# 3.回溯
def backtrack(ls,nums,stk):
if sum(nums) in narcissus_nums:
stk.append("".join(ls))
res.append(stk[:])
stk.pop()
return
for i in range(1,len(nums)):
if sum(nums[:i]) in narcissus_nums:
stk.append("".join(ls[:i]))
backtrack(ls[i:],nums[i:],stk)
stk.pop()
res = [] # 只有满足条件的分组才会存入res
backtrack(ls,nums,[])
# 4.输出
if len(res) == 0: # 分割不成功,res为空
print(0)
elif len(res) == 1: # 分割唯一,输出子串数
print(len(res[0]))
else: # 分割不唯一,事实上 len(res) > 1
print(-1)
仅供参考!如有错误,欢迎指正!
第二题:内存资源分配
题目描述
有一个简易内存池,内存按照大小粒度分类,每个粒度有若干个可用内存资源,用户会进行一系列内存申请,需要按需分配内存池中的资源,返回申请结果成功失败列表。
分配规则如下:
1.分配的内存要大于等于内存申请量,存在满足需求的内存就必须分配,优先分配粒度小的,但内存不能拆分使用。
2.需要按申请顺序分配,先申请的先分配。
3.有可用内存分配则申请结果为true,没有可用内存分配则返回false。
注:不考虑内存释放。
输入描述
第一行为内存池资源列表,包含内存粒度数据信息,粒度数据间用逗号分割,一个粒度信息内部用冒号分割,冒号前为内存粒度大小,冒号后为数量。资源列表不大于1024,每个粒度的数量不大于4096。
第二行为申请列表,申请的内存大小间用逗号分隔。申请列表不大于100000。
输出描述
输出为内存池分配结果。
示例
输入:
64:2,128:1,32:4,1:128
50,36,64,128,127
输出:
true,true,true,false,false
说明:
内存池资源包含:64K共2个、128K共1个、32K共4个、1K共128个的内存资源;
针对50,36,64,128,127的内存申请序列,分配的内存依次是:64,64,128,NULL,NULL,
第三次申请内存时已经将128分配出去,因此输出结果是:true,true,true,false,false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 以下代码用例通过率为:95.8%
s = input().split(",")
a = list(map(int,input().split(",")))
ds = {}
ls = ""
for i in s:
size,n = map(int,i.split(":"))
ls += n * (" "+str(size))
ds[size] = n
tls = sorted(list(map(int,ls.split())))
res = []
def check(i):
for j,v in enumerate(tls):
if v >= i:
tls.pop(j)
return "true"
return "false"
for i in a:
res.append(check(i))
print(",".join(res))
第三题:模拟内存分配
请实现一个简易内存池,根据请求命令完成内存分配和释放。
内存池支持两种操作命令,REQUEST和RELEASE,其格式为:
REQUEST=请求的内存大小 表示请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出error。
RELEASE=释放的内存首地址 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址则输出error。
注意:
1.内存池总大小为100字节。
2.内存池地址分配必须是连续内存,并优先从低地址分配。
3.内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。
4.不会释放已申请的内存块的中间地址。
5.释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。
解答要求
时间限制: 1000ms, 内存限制: 256MB
首行为整数 N , 表示操作命令的个数,取值范围:0 < N <= 100。
接下来的N行, 每行将给出一个操作命令,操作命令和参数之间用 “=”分割。
输入样例1
2
REQUEST=10
REQUEST=20
输出样例1
0
10
输入样例2
5
REQUEST=10
REQUEST=20
RELEASE=0
REQUEST=20
REQUEST=10
输出样例2
0
10
30
0
图片说明
1
2
3
# 以下代码用例通过率:15% 哈哈!所有不会也不要留空白哦
N = int(input())
print("error")