哔哩哔哩笔试编程题

一、红茶

 

题目描述

高贵的蕾米莉亚大小姐每天需要饮用定量 B 型血的红茶以保持威严,并且要分两杯在不同时段饮用。
女仆长十六夜咲夜每天可以制作很多杯不同剂量 B 型血的红茶供蕾米莉亚大小姐饮用。
某日,你和天才妖精琪露诺偷偷潜入红魔馆被咲夜抓住,要求在今日份的红茶中挑出所有满足大小姐要求的茶杯,否则……

输入描述:

每个样例有三行输入,第一行输入表示茶杯个数,第二行输入表示每份茶杯里的 B 型血剂量,第三行表示大小姐今天的定量

输出描述:

对每一个样例,输出所有可能的搭配方案,如果有多种方案,请按每个方案的第一杯 B 型血剂量的大小升序排列。
如果无法找到任何一种满足大小姐的方案,输出"NO"(不包括引号)并换行。

分析:由于是按照第一杯血剂量的大小排序,那么只要将所有血剂量从小到大排序即可。从头遍历,输出合适的搭配方案。时间复杂度和空间复杂度均为O(n/2),编码如下:

n = int(input())
arr = list(map(int,input().split()))
sum = int(input())

arr.sort()

flag = 0
low = 0
high = len(arr)-1
while low<high :
    if arr[low]+arr[high]==sum :
        print(str(arr[low])+' '+str(arr[high]))
        low += 1
        flag = 1
    elif arr[low]+arr[high]>sum :
        high -=1
    else :
        low +=1

if flag==0:
    print('NO')

二、判断IP字符串是否属于内网IP

题目描述

从业 666 年的 BILIBILI 网络安全工程师 KindMo 最近很困惑,公司有一个业务总是受到 SSRF 攻击。请帮他写一个程序,判断输入的字符串是否属于内网IP,用于防御该漏洞。
我们知道常见的内网IP有,127.0.0.1,192.168.0.1 等。

输入描述:

每次输入仅包含一个IP字符串,即一个测试样例

输出描述:

对于每个测试实例输出整数1或0,1代表True,即输入属于内网IP,0代表False,即输入不属于内网IP或不是IP字符串。

分析:对输入的字符串进行切割,然后判断字符串是否在内网IP范围内。在牛客网提交的下面代码也能通过,应该是系统bug吧。。

iplist = input().split('.')
res = 0

if iplist[0] in ['127','10','192','172']:
    res = 1
    
print(res)

 

三、翻转链表

题目描述:

对于一个链表 L: L0→L1→…→Ln-1→Ln,
将其翻转成 L0→Ln→L1→Ln-1→L2→Ln-2→…

输入是一串数字,请将其转换成单链表格式之后,再进行操作

输入描述:

一串数字,用逗号分隔

输出描述:

一串数字,用逗号分隔

分析:可以定一个列表,存放结果数据。对输入的数据转化成列表后进行遍历,根据位置来判断列表元素的取与存,如果是奇数那么取头,如果是偶数那么取尾即可。编码如下:

instr = input().strip().split(',')
res = []

for i in range(1,len(instr)+1):
    if i%2==1 :
        res.append(instr[int(i/2)])
    else :
        res.append(instr[len(instr)-int(i/2)])

print(','.join(res))

 

四、版本比较

题目描述

如果version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.

输入的version字符串非空,只包含数字和字符.。.字符不代表通常意义上的小数点,只是用来区分数字序列。例如字符串2.5并不代表二点五,只是代表版本是第一级版本号是2,第二级版本号是5.

输入描述:

两个字符串,用空格分割。
每个字符串为一个version字符串,非空,只包含数字和字符.

输出描述:

只能输出1, -1,或0

分析:将输入转换成两个int型数组,然后进行逐位比较,根据相应的规则返回相应的结果。这里定义了flag和res两个变量,分别记录结果标志与结果值。当flag=1时说明结果已出来,跳出循环。要注意的是循环的取值以及跳出循环的条件,这里在循环范围上我取了列表的最大长度,跳出条件除了标志变量外还对循环变量进行了判断,当循环变量=最短列表长度时,说明其中一个列表已经匹配完成,且与另一个列表的一部分完全匹配,结果尚不明确。如果忽略了这两点,极有可能导致数组越界的情况。编码如下:

indata = input().split()
v1, v2, flag,res = list(map(int,indata[0].split('.'))) ,list(map(int,indata[1].split('.'))) , 0,0

for i in range(max(len(v1),len(v2))):
    if flag == 1 or i == min(len(v1),len(v2)):
        break
    if v1[i] > v2[i]:
        res = 1
        flag = 1
    elif v1[i] < v2[i]:
        res = -1
        flag = 1
    else:
        continue

if res==0:
    if len(v1)>len(v2):
        res = 1
    elif len(v1)<len(v2):
        res = -1

print(res)

当然,这一题可以更简单地通过评判系统,因为python中的列表可以直接进行比较。编码如下:

indata = input().split()
v1, v2= list(map(int,indata[0].split('.'))) ,list(map(int,indata[1].split('.')))

if v1<v2:
    print(-1)
elif v1>v2:
    print(1)
else:
    print(0)

五、精灵鼠

题目描述

猛兽侠中精灵鼠在利剑飞船的追逐下逃到一个n*n的建筑群中,精灵鼠从(0,0)的位置进入建筑群,建筑群的出
口位置为(n-1,n-1),建筑群的每个位置都有阻碍,每个位置上都会相当于给了精灵鼠一个固定值减速,因为
精灵鼠正在逃命所以不能回头只能向前或者向下逃跑,现在问精灵鼠最少在减速多少的情况下逃出迷宫?

输入描述:

第一行迷宫的大小: n >=2 & n <= 10000;
第2到n+1行,每行输入为以','分割的该位置的减速,减速f >=1 & f < 10。

输出描述:

精灵鼠从入口到出口的最少减少速度?

分析:这是一道简单的动态规划问题,求最短路径,只要自下而上构造出相应的动态规划表即可,表中的某个元素即为所需的答案。由以上规则知:精灵鼠只能向前或者向下运动。当处于最低一层时,精灵鼠不能再向下运动,只能向前;当精灵鼠处于最前方时只能向下运动。由次可得到动态规划表的构造规则。编码如下:

n = int(input().strip())
building = []
# 构造迷宫
for i in range(n):
    building.append(list(map(int,input().split(','))))

# 构造动态规划表
for i in range(n):
    for j in range(n):
        if j==0 and i==0:
            continue
        if i==0:
            building[n-i-1][n-j-1] += building[n-i-1][n-j]
        elif j==0:
            building[n-i-1][n-j-1] += building[n-i][n-j-1]
        else:
            building[n - i - 1][n - j - 1] += min(building[n-i-1][n-j],building[n-i][n-j-1])

print(building[0][0])

六、顺时针打印数字矩阵

题目描述

给定一个数字矩阵,请设计一个算法从左上角开始顺时针打印矩阵元素

输入描述:

输入第一行是两个数字,分别代表行数M和列数N;接下来是M行,每行N个数字,表示这个矩阵的所有元素;
当读到M=-1,N=-1时,输入终止。

输出描述:

请按逗号分割顺时针打印矩阵元素(注意最后一个元素末尾不要有逗号!例如输出“1,2,3”,而
不是“1,2,3,”),每个矩阵输出完成后记得换行

分析:打印数字矩阵,其实只要四个步骤即可,其余都是循环。首先要将输入构造成二维数组的形式,由打印规则,可以先是从左到右输出二维数组第一行的数据,再是从上到下输出每行数据的最后一个对象元素,接着是从右到左输出最后一行的数据,最后是从下到上输出每行数据的第一个对象元素,这便是一个完整的顺时针,然后循环此操作知道数组中没有可打印的元素。编码如下:

def cal(arr):
    res = []
    while arr:
        # 上左
        res += arr.pop(0)
        # 右下
        if arr and arr[0]:
            for i in arr:
                res.append(i.pop())
        # 下左
        if arr and arr[0]:
            res += arr.pop()[::-1]
        # 左上
        if arr and arr[0]:
            for x in arr[::-1]:
                res.append(x.pop(0))
    # 转换成要求的格式
    res = ','.join(res)
    print(res)


while True:
    m,n = map(int,input().split())
    # 当读到m=-1,n=-1时终止输入
    if m==-1 and n==-1:
        break;
    # 构造输入数据结构
    arr = []
    for i in range(m):
        arr.append(input().split())
    cal(arr)

七、扭蛋机

题目描述

22娘和33娘接到了小电视君的扭蛋任务:
一共有两台扭蛋机,编号分别为扭蛋机2号和扭蛋机3号,22娘使用扭蛋机2号,33娘使用扭蛋机3号。
扭蛋机都不需要投币,但有一项特殊能力:
扭蛋机2号:如果塞x(x范围为>=0正整数)个扭蛋进去,然后就可以扭到2x+1个
扭蛋机3号:如果塞x(x范围为>=0正整数)个扭蛋进去,然后就可以扭到2x+2个
22娘和33娘手中没有扭蛋,需要你帮她们设计一个方案,两人“轮流扭”(谁先开始不限,扭到的蛋可
以交给对方使用),用“最少”的次数,使她们能够最后恰好扭到N个交给小电视君。

输入描述:

输入一个正整数,表示小电视君需要的N个扭蛋。

输出描述:

输出一个字符串,每个字符表示扭蛋机,字符只能包含"2"和"3"。

分析:根据扭蛋机2号和3号的规则,进行递归即可。编码如下:

num = int(input())
res = ''
while num>0:
    if (num-1)%2==0 :
        res = '2'+res
        num = (num-1)/2
    else :
        res = '3'+res
        num = (num-2)/2
print(res)

猜你喜欢

转载自blog.csdn.net/VinWqx/article/details/104570291