python(牛客)试题解析2 - 中等

2023-01-04,,,

导航

一、NC192 二叉树的后序遍历

二、NC117 合并二叉树

三、求长度最长的的连续子序列使他们的和等于sum

四、按顺序取出固定长度内容并合并两个数组为一个新数组

五、输出所有结果小于k的整数组合到一起的最小交换次数

六、取集合中满足条件的数据对组成新的集合

七、太阳能板最大面积

八、计算出满足能力最低要求的最大数量团队组合

九、将虚拟IPv4地址转换为一个32位的整数

十、将一队小朋友以“高”“矮”“高”“矮”顺序排列

十一、将探险队的坐标位置中挑选出相对总部的距离最远的坐标位置

- - - - - - - - - - 分-割-线 - - - - - - - - - - -
一、NC192 二叉树的后序遍历

描述:给定一个二叉树,返回他的后序遍历的序列。
解析:使用递归的方法去处理二叉树节点遍历的情况,后序遍历先访问左子树,再访问右子树,最后访问根节点
测试数据:

示例1
输入:
{1,#,2,3}
复制
返回值:
[3,2,1]
示例2
输入:
{1}
复制
返回值:
[1]

class Solution:
def postorder(self, list: List[int], root: TreeNode):
# 遇到空节点则返回
if not root:
return
# 先去左子树
self.postorder(list, root.left)
# 再去右子树
self.postorder(list, root.right)
# 最后访问根节点
list.append(root.val) def postorderTraversal(self , root: TreeNode) -> List[int]:
res = []
# 递归后序遍历
self.postorder(res, root)
return res

二、NC117 合并二叉树

描述:已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。

解析:利用递归方式,新节点值设置为现有两个节点值的和,新节点左右子树分别用现有子树左右节点为参数进行递归

测试数据:

输入:

示例1
输入:
{1,3,2,5},{2,1,3,#,4,#,7}
复制
返回值:
{3,4,5,5,4,#,7}
示例2
输入:
{1},{}
返回值:
{1}

class Solution:
def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
if not t1:
return t2
if not t2:
return t1
newnode = TreeNode(t1.val+t2.val)
newnode.left = self.mergeTrees(t1.left,t2.left)
newnode.right = self.mergeTrees(t1.right,t2.right)
return newnode

三、求长度最长的的连续子序列使他们的和等于sum

描述:有N个正整数组成的一个序列,给定一个整数sum
求长度最长的的连续子序列使他们的和等于sum
返回次子序列的长度,如果没有满足要求的序列 返回-1
示例:
输入序列仅由数字和英文逗号构成,数字之间采用英文逗号分割
输入:
1,2,3,4,2
6
输出:
3
解析:
1,2,3和4,2两个序列均能满足要求,所以最长的连续序列为1,2,3 因此结果为3
输入:
1,2,3,4,2
20
输出:
-1
解析:两次for循环遍历数组,连续累加值等于sum,时记录长度
l = list(map(int, input().split(",")))
s = int(input())
a = []
for i in range(len(l)):
sum_ = 0
for j in range(i,len(l)):
sum_ += l[j]
if sum_ == s:
a.append(len(l[i:j+1]))
break
print(max(a) if len(a)>0 else -1)

四、按顺序取出固定长度内容并合并两个数组为一个新数组

描述:现在有多组整数数组,需要将他们合并成一个新的数组,合并规则从每个数组里按顺序取出固定长度的内容
合并到新的数组,取完的内容会删除掉,如果改行不足固定长度,或者已经为空,则直接取出剩余部分的内容放到新的数组中继续下一行
输入描述:
第一 行每次读取的固定长度,长度0<len<10
第二行是整数数组的数目,数目 0<num<10000
第3~n行是需要合并的数组,不同的数组用换行分割,元素之间用逗号分割,最大不超过100个元素
示例:
输出描述:输出一个新的数组,用逗号分割示例 输入:
3
2
2,5,6,7,9,5,7
1,7,4,3,4
输出:
2,5,6,1,7,4,7,9,5,3,4,7
说明:
输入:
4
3
1,2,3,4,5,6
1,2,3
1,2,3,4
输出:
1,2,3,4,1,2,3,1,2,3,4,5,6
解析:将多个数组写入一个二维的数组内,遍历二维数组,获取最小的可弹出长度,弹出后写入新的数组内
size = int(input())
num = int(input())
l1,l2,total = [],[],0
for i in range(num):
tmp = list(map(str,input().split(",")))
l1.append(tmp)
total += len(tmp)
while len(l2)<total:
for i in l1:
if len(i)==0:
break
else:
tmp_size = min(size,len(i))
for j in range(tmp_size):
l2.append(i.pop(0))
print(",".join(l2))

五、输出所有结果小于k的整数组合到一起的最小交换次数

描述:给出数字k,请输出所有结果小于k的整数组合到一起的最小交换次数。  组合一起是指满足条件的数字相邻,不要求相邻后在数组中的位置。
数据范围 -100 <= k <= 100 -100 <= 数组中的值 <= 100
示例:
第一行输入数据:第二行输入k数值:
1 3 1 4 0
2
输出 1
样例输入2:
第一行输入数据:第二行输入k数值
0 0 1 0
2
输出 0
样例输入3: 第一行输入数据:第二行输入k数值:
2 3 2
1
输出 0
解析:取出原数组内所有小于k的数字的下标位置组成新的数组,并遍历数组内记录最小的距离值
l1 = list(map(int,input().split()))
k = int(input())
l = []
a = []
for i in range(len(l1)):
if l1[i]< k:
l.append(i)
if len(l) > 1:
for i in range(len(l)):
for j in range(i+1,len(l)):
s = abs(l[i]-l[j])-1
a.append(s)
print(min(a) if len(l) > 1 else 0)

六、取集合中满足条件的数据对组成新的集合

描述:同一个数轴x有两个点的集合A={A1,A2,...,Am}和B={B1,B2,...,Bm}  A(i)和B(j)均为正整数
A、B已经按照从小到大排好序,AB均不为空
给定一个距离R 正整数,列出同时满足如下条件的(A(i),B(j))数对
1. A(i)<=B(j)
2. A(i),B(j)之间距离小于等于R
3. 在满足1,2的情况下每个A(i)只需输出距离最近的B(j)
4. 输出结果按A(i)从小到大排序
输入描述
第一行三个正整数m n R
第二行m个正整数 表示集合A
第三行n个正整数 表示集合B
输入限制
1<=R<=100000
1<=n,m<=100000
1<= A(i),B(j) <= 1000000000
输出描述
每组数对输出一行 A(i)和B(j),以空格隔开
示例:
输入
4 5 5
1 5 5 10
1 3 8 8 20
输出
1 1
5 8
5 8
解析:解析两个数组,取出满足条件的数据,经过排序后输出
line1 = list(map(int,input().split()))
A = list(map(int,input().split()))
B = list(map(int,input().split()))
m,n,R = line1[0],line1[1],line1[2]
s,temp=[],{}
for i in A:
for j in B:
if i<=j and abs(j-i)<=R:
temp[j-i] = (i,j)
temp1 = sorted(temp.items(),key=lambda x:x[0])
if temp1:
s.append(temp1[0][1])
temp={}
for i in s:
print(" ".join(map(str,i)))

七、太阳能板最大面积

描述:给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。如图:
现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为1个单位长度,计算如何选择两根支柱可以使太阳能板的面积最大。
输入描述:
10,9,8,7,6,5,4,3,2,1
注:支柱至少有2根,最多10000根,能支持的高度范围1~10^9的整数。柱子的高度是无序的,例子中递减只是巧合。
输出描述:
可以支持的最大太阳能板面积:(10米高支柱和5米高支柱之间)
25
示例:
输入
10,9,8,7,6,5,4,3,2,1
输出
25

nums = list(map(int,input().split(",")))
max_area=0
for i in range(len(nums)-1):
for j in range(i+1,len(nums)-1):
temp_area= min(nums[i:j+1])*(j-i)
if temp_area > max_area:
max_area = temp_area
print(max_area)

八、计算出满足能力最低要求的最大数量团队组合

描述:用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或2人组成,
且1个人只能参加1个团队, 请计算出最多可以派出多少支符合要求的团队?
输入描述:
5
3 1 5 7 9
8
第一行数组代表总人数,范围[1,500000]
第二行数组代表每个人的能力,每个元素的取值范围[1, 500000],数组的大小范围[1,500000]
第三行数值为团队要求的最低能力值,范围[1, 500000]
输出描述:
3

解析:分单人组团与多人组团分别处理,两人的团队分别先按照能力从小到大排序并各种可能记录二维数组,记录sum的最小值后写入最终的数组,此时累计count

n = int(input())
l1 = list(map(int,input().split()))
k = int(input())
l = []
l2 = []
l3 = []
for i in l1:
if i<k:
l.append(i)
count = n - len(l)
l = sorted(l) #[1,3,5,7]
if len(l)>1:
for i in range(len(l)):
for j in range(i+1,len(l)):
if l[i]+l[j]>=k and (l[i] not in l3) and (l[j] not in l3):
l2.append([l[i],l[j]])
if len(l2)>0:
sum_max=0
index=0
for k in range(len(l2)):
tmp_sum = sum(l2[k])
if tmp_sum > sum_max:
sum_max = tmp_sum
index = k
l3.append(l2[k][0])
l3.append(l2[k][1])
count += 1
l2 = []
print(count)

 九、将虚拟IPv4地址转换为一个32位的整数

描述:存在一种虚拟IPv4地址,由4小节组成,每节的范围为0~128,以#号间隔,格式如下:
(1~128)#(0~255)#(0~255)#(0~255)
请利用这个特性把虚拟IPv4地址转换为一个32位的整数,IPv4地址以字符串形式给出,要求每个IPv4地址只能对应到唯一的整数上。
如果是非法IPv4,返回invalid IP

示例
输入:
100#101#1#5
输出
1684340997

while True:
try:
m = input()
try:
n = list(map(int,m.split("#")))
if n[0]>128 or n[1]>255 or n[2]>255 or n[3]>255 or len(n)!=4:
print("invalid IP")
continue
res = ""
for i in n:
res += str("%08d" % (int(bin(i)[2:])))
print(int(res,2))
except:
print("invalid IP")
except:
break

十、将一队小朋友以“高”“矮”“高”“矮”顺序排列

描述:现在有一队小朋友,他们高矮不同,,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}
我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,
每一个“高”位置的小朋友要比相邻的位置高或者相等;
每一个“矮”位置的小朋友要比相邻的位置矮或者相等;
要求小朋友们移动的距离和最小,第一个从“高”位开始排,输出最小移动距离即可"""
示例:
1.输入:
4 1 3 5 2
输出:4 1 5 2 3
2.输入:
1 1 1 1 1
输出:1 1 1 1 1
说明:
相邻位置可以相等
3.输入:
xxx
输出:[]
说明:
出现非法参数情况,返回空数组

解析:设置标记,通过循环一步步处理并在每一步处理后改变标记的布尔值

try:
l = list(map(int,input().split()))
flag=True
for i in range(len(l)-1):
for j in range(i+1,len(l)-1):
if flag:
if not l[i]>=l[j]:
l[i],l[j]=l[j],l[i]
flag = not flag
break
else:
if not l[j]>=l[i]:
l[i],l[j]=l[j],l[i]
flag = not flag
break
res=""
for i in l:
res += str(i)+" "
print(res.strip())
except:
print("[]")

十一、将探险队的坐标位置中挑选出相对总部的距离最远的坐标位置

描述:探险队负责对地下洞穴进行探险。 探险队成员在进行探险任务时,随身携带的记录器会不定期地记录自身的坐标,但在记录的间隙中也会记录其他数据。 探索工作结束后,探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足迹位置。
仪器记录坐标时,坐标的数据格式为(x,y),如(1,2)、(100,200),其中0<x<1000,0<y<1000。同时存在非法坐标,如(01,1)、(1,01),(0,100)属于非法坐标。
设定探险队总部的坐标为(0,0),某位置相对总部的距离为:x * x+ y * y。
若两个座标的相对总部的距离相同,则第一次到达的坐标为最远的足迹。
若记录仪中的坐标都不合法,输出总部坐标(0,0)。 备注:不需要考虑双层括号嵌套的情况,比如sfsdfsd((1,2))。
输入描述:
字符串,表示记录仪中的数据。
ferga13fdsf3(100,200)f2r3rfasf(300,400)
输出描述:
字符串,表示最远足迹到达的坐标。
如: (300,400)
示例 1:
输入
ferg(3,10)a13fdsf3(3,4)f2r3rfasf(5,10)
1
输出
(5,10)
1
说明
记录仪中的合法坐标有3个: (3,10), (3,4), (5,10),其中(5,10)是相距总部最远的坐标, 输出(5,10)。
示例 2:
输入
asfefaweawfaw(0,1)fe
1
输出
(0,0)

解析:首先进行字符串的分割,提取到坐标的位置,排除异常的坐标后取最大值的坐标并输出

l1 = input().split("(")[1:]
l2 = []
res =[]
max_area=0
for i in l1:
i = i.split(")")[0]
l2.append(i)
for i in l2:
x = i.split(",")[0]
y = i.split(",")[1]
if str(x) == "0" or x.startswith("0") or str(y) == "0" or y.startswith("0"):
res = [0,0]
else:
x,y=int(x),int(y)
tmp_area = x ** 2 + y ** 2
if tmp_area > max_area:
max_area = tmp_area
res = [x,y]
print(f"({res[0]},{res[1]})")

python(牛客)试题解析2 - 中等的相关教程结束。

《python(牛客)试题解析2 - 中等.doc》

下载本文的Word格式文档,以方便收藏与打印。