奇安信2021春招笔试-测试、服务端python方向

流程及心得:2月28晚上投了奇安信的测试、服务端python方向两个岗位;3月4号晚上七点通知3月6号下午测试岗笔试,觉得时间有点紧,赶紧去刷测试岗的题,结果3月5号上午10点又收到服务端的笔试通知,我???最后带着积攒经验的心态,我继续刷了几题,然后看了一些之前刷过的leetcode。然后3月六号下午就考试,先考了2个小时的服务端,接着考了两个小时的测试岗,感觉整个人都虚了,庆幸的是两套题有重叠的题目,编程题是一样的,但是做前一道的时候,没什么经验,瞎写一通,没写出来,第二套才写出来了,但也没有完全通过。第一题的奶牛产奶我到现在没明白为啥没有完全通过,可能是我题目没看懂吧。第二题的最短路径问题,在写的时候给自己挖了几个坑,考试结束了才完全debug,现在也不知道改过之后的能不能完全通过。。。

第一题大致是:奶牛产奶(我就纳闷了,你们为什么事后都记得原题)。奶牛吃草后产奶,如果吃草多的奶牛比吃草少的奶牛产奶少,它们就经常打架;吃草相同的奶牛不打架;产奶相同的奶牛也不打架。算出满足两个条件:不打架,一天之内产奶最多的总产奶量。
我的思路就是,两个循环暴力求解,先选出不打架的奶牛,再把它们的牛奶产量相加。题目传给了两个列表,分别是每头牛吃掉草的捆数grass,和牛奶产量milk。

def solution(grass,milk):
	n = len(grass)#计算牛的数量
	temp = []#记录是否会打架
	for i in range(n):
		temp.append(0)#默认不打架
	#开始判断它们时间是否会打架,两两之间比较,例如有5头
	for i in range(n-1):#0,1,2,3,4
		for j in range(n-i-1):#例如当i=0,表示第一头牛需要与后四头进行比较
			if grass[i]>grass[j+1] and milk[j]<milk[j+1]:#我觉得我是这里少判断了
				temp[i]=1#会打架
	final = 0#中产量
	for i in range(n):
		if temp[i]==0:#不打架,可以选
			final = final + milk[i]
	return final

最后通过率是50%,我琢磨着题目不打架那里还要判断,但没弄明白。
第二题是最短路径问题:
例图是这样
在这里插入图片描述
输入是:
6
0 5
0 1 2
0 2 3
0 4 5
1 4 1
1 5 4
2 3 6
3 4 3
3 5 4
4 5 5
0 0 0
第一行表示顶点个数,第二行表示出发和目标顶点,接下来每行是两个顶点之间的路径,如0 1 2表示顶点0和1的路径是2,输入0 0 0结束。
输出最短路径。
我在写嵌套时给自己挖了无数坑,考完了才debug完,还忘记考虑初始顶点和结束顶点,最后也没完全通过。。。
这是默认最大一个数就是顶点的情况,大致思路就是把所有的路径存到一个二维数组,然后不停相加比较,思路有点乱,先贴代码,晚点重新看Dijkstra算法后再改吧。

import sys
    # 读取第一行的n
n = int(sys.stdin.readline().strip())#顶点数
line = sys.stdin.readline().strip()
temp = list(map(int, line.split()))
start,end = temp[0],temp[1]#开始和结束顶点
#保存路径
mid = []
begin = []#mid的拷贝
work = []#记录是否更改过
for i in range(n-1):
    mid.append(list())
    begin.append(list())
    work.append(list())
for i in range(n-1):
    for j in range(n-1):
        mid[i].append(0)
        begin[i].append(0)
        work[i].append(0)

line = sys.stdin.readline().strip()
temp = list(map(int, line.split()))

while temp[2]!=0:
# 读取每一行
    mid[temp[0]][temp[1]-1]=temp[2]
    begin[temp[0]][temp[1]-1]=temp[2]
    #print(mid)
    line = sys.stdin.readline().strip()
        # 把每一行的数字分隔后转化成int列表
    temp = list(map(int, line.split()))

for i in range(n-1):
    for j in range(n-2):
        if mid[i][j]!=0:
            for z in range(n-1):
                #print("beg",begin)
                if mid[j+1][z]!=0 and work[j+1][z]==0:#完全没改过,可以改
                    mid[j+1][z]= mid[j+1][z]+mid[i][j]
                    work[j+1][z]=1
                    #print("why",mid)
                    #print("agin",begin[i+1][z],mid[i][j])
                elif mid[j+1][z]!=0 and work[j+1][z]==1 and (begin[j+1][z]+mid[i][j]<mid[j+1][z]):#改过
                    mid[j+1][z]= begin[j+1][z]+mid[i][j]
                    #print("not",mid)
					
minNum=0
for i in range(n-1):
    if mid[i][4]!=0:
        minNum=mid[i][4]
for i in range(n-1):
    if minNum > mid[i][4] and mid[i][4]!=0:
        minNum=mid[i][4]
print(minNum)

其他的题是单项选择题和不定项选择题,分值大致两分每题,具体多少,连续做两套之后我也搞混了。知识点大致是数据结构操作系统计算机网络数据库,还有测试的一些基础知识。数据结构好像有二叉树的形状,链表删除、插入,栈;操作系统有进程,线程,忘了;计网有二层交换机,BGP协议,tcp握手,A类网主机数;数据库有主键,约束,忘了。
测试的也是一些基础,都忘了,还有几题在牛客的专项里有刷到过。
总之奇安信的题其实还好,但我本身编程题还不怎么熟练,还要刷很多题,选择题题有一些基础也忘记了,就当作慢慢积累吧,希望接下来能越来越好。欢迎也写了两套题的同学交流补充!!

第二题补充

(参考:李春葆 《数据结构教材第5版》)
在这里插入图片描述

def Dijkstra(n,temp,start,end):#n表示顶点数,temp为邻接表,start,end为开始,结束顶点
    dist = list()
    S = [0 for x in range(0, n)]#S[i]=1表示顶点i在S中,否则在U中
    path = [-1 for x in range(0, n)]#path[i]表示源点到点i的前一个顶点
    for i in range(n):
        if temp[start][i]!=0:
            path[i] = start#如果顶点i到源点有直接路径,顶点i的前一个顶点为源点
            dist.append(temp[start][i])  # dist[i]表示源点到该点的路径
        else:
            dist.append(float("inf"))
    print("dist1",dist)
    S[start],path[start] = 1,0 #源点编号放入S中
    u = 0
    for i in range(n-1):#每轮循环求到一个顶点的最短路径
        Minnum = float("inf")#置最大初始
        for j in range(n):
            if S[j] == 0 and dist[j] < Minnum:  #找出U中的最小值
                u = j
                Minnum = dist[j]
        print("加入的点",u)
        S[u] = 1    #顶点u加入S
        for j in range(n):
            if S[j]==0:#修改U中的顶点的最短路径
                # 如果顶点j到u有直接路径,且他们相加比原来源点到j更短
                if temp[u][j]!=0 and dist[u]+temp[u][j]<dist[j]:
                    dist[j] = dist[u] + temp[u][j]  #修改源点到j的最短路径
                    path[j] = u #修改源点到j的前一个顶点
        # print("dist", dist)
    print("最短路径为:",dist[end])
# temp = [[0,2,3,0,5,0],    #例子
#         [2,0,0,0,1,4],
#         [3,0,0,6,0,0],
#         [0,0,6,0,3,4],
#         [5,1,0,3,0,5],
#         [0,4,0,4,5,0]]
import sys
# 读取第一行的n
n = int(sys.stdin.readline().strip())#顶点数
line = sys.stdin.readline().strip()
mid = list(map(int, line.split()))
start,end = mid[0],mid[1]#开始和结束顶点
#保存路径

temp = [[0] * n for i in range(n)]   #创建一个6行6列的二维数组
# print("temp",temp)
line = sys.stdin.readline().strip()
mid = list(map(int, line.split()))

while mid[2]!=0:
# 读取每一行
    temp[mid[0]][mid[1]]=mid[2]
    # print("temp",temp)
    temp[mid[1]][mid[0]]=mid[2]
    line = sys.stdin.readline().strip()
        # 把每一行的数字分隔后转化成int列表
    mid = list(map(int, line.split()))
Dijkstra(n,temp,start,end)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值