字节跳动2019年春季实习招聘机器学习算法岗第二批笔试题及解答

以下解答是我自己的解法,有待优化,仅供参考!

第一题:.

题目描述
公司的程序员不够用了,决定把产品经理都转变为程序员以解决开发时间长的问题。
在给定的矩形网格中,每个单元格可以有以下三个值之一:
.值0代表空单元格;

.值1代表产品经理;

.值2代表程序员;
每分钟,任何与程序员(在4个正方向上)相邻的产品经理都会变成程序员。
返回直到单元格中没有产品经理为止所必须经过的最小分钟数。
如果不可能,返回-1。

输入描述:
不固定多行〈行数<= 10),毎行是按照空格分割的数字(不固定,毎行数字个数<= 10)

其中每个数组项的取值仅为0、1、2三种

 (读取时可以按行读取,直到读取到空行为止,再对读取的所有行做转换处理)

输出描述:

如果能够将所有产品经理变成程序员,则输出最小的分钟数。

 如果不能够将所有的产品经理变成程序费,则返回-1.

示例1:

0 2

1 0

输出:

-1

 

示例2:

输入:

1 2 1

1 1 0

0 1 1

输出:

3

解题思路:

按照给的规则更新即可,每更新一次就对时间变量加1.

停止条件为上一轮中没有1变成2,但是矩阵中还有1,这种情况说明有1更新不到,返回-1.

另外一种停止条件是矩阵中不存在1了。

更新时有一个小技巧,将周围的变量已经更新过的2记录在字典里,避免重复搜索,减少时间复杂度。

代码:

import copy
def JudgeExist1(InputList):
    for InputList_i in InputList:
        if 1 in InputList_i:
            return True
    return False
def Trans2To1(InputList):
    global TranstedDict
    converted=0
    InputList=InputList
    InputList_temp=copy.deepcopy(InputList)
    for i in range(row):
        for j in range(column):
            if InputList[i][j]==2:
                #print("(i,j)=",(i,j))
                if (i,j) in TranstedDict:#如果已经转换过了,则不再转换
                    continue
                else:
                    if i-1>=0 and InputList[i-1][j]==1:
                        InputList_temp[i - 1][j]=2
                        converted=1
                    if i+1<row and InputList[i+1][j]==1:
                        InputList_temp[i + 1][j]=2
                        converted = 1
                    if j-1>=0 and InputList[i][j-1]==1:
                        InputList_temp[i][j - 1]=2
                        converted = 1
                    if j+1<column and InputList[i][j+1]==1:
                        InputList_temp[i][j + 1]=2
                        converted = 1
                    TranstedDict[(i,j)]=1
                #print("InputList_temp=",InputList_temp)
    return (converted,InputList_temp)
global TranstedDict
TranstedDict={}
stopword = ''
InputList=[]
for line in iter(input, stopword):#iter是一个迭代器,第二个参数指定了迭代停止的条件
    InputList.append(list(map(int, line.split())))
#print("InputList=",InputList)
row=len(InputList)
MinT=0
if row==0:
    MinT = -1
else:
    column=len(InputList[0])
    #print("(row,column)=", (row, column))
    while JudgeExist1(InputList):
        converted,InputList=Trans2To1(InputList)
        #print("InputList=",InputList)
        if converted==0:
            MinT=-1
            break
        else:
            MinT+=1
            continue

print(MinT)

第二题:

题目描述:

 

 小明是名算法工程师, 同时也是名铲屎官。 某天,他突发奇想,想从猫咪的视频里挖据一些猫咪的运动信息。为了提取运动信息,他需要从视频的每一帧提取“猫咪特征”。一个猫咪特征是一个两维的vectorc<x, y>。如果x_1=x 2andy_1=y _2, 那么这俩是同一个特征。

      因此,如果猫咪特征连续一致,可以认为猫咪在运动。也就是说,如果特征<a, b>在持续帧里出现,那么它将构实特征运动。比如,特征<a b>在第2/3/4/7/8帧出现,那么该特征将形成两个特征运动2-3- 4和7-8。

现在,给定每一帧的特征, 特征的数量可能不一样。小明期望能找到最长的特征运动。

输入描述:

第一行包含一个正整数N,代表测试用例的个数。
每个测试用例的第一行包含一个正整数M, 代表视频的帧数。

接下来的M行,每行代表一帧。其中,第一个数字是该帧的特征个数,接下来的数字是在特征的取值:比如样例输入第三行里,2代表该帧有两个猫咪特征,<1, 1>和<2, 2>
所有用例的输入特征总数和<100000

N满足1<=N<=100000. M满足1<=M<=10000.一帧的特征个数满足S<=10000。

特征取值均为非负整数。

输出描述:对每一个测试用例,输出特征运动的长度作为一行

示例1:

1

8

2 1 1 2 2

2 1 1 1 4

2 2 2 1 4

0

0

1 1 1

1 1 1

输出:

3

说明:

特征<1,1>在连续的帧中连续出现3次,相比其他特征连续出现的次数大,所以输出3

备注:

如没有长度大于2的特征运动,返回1

代码:(思路就是找每种特征的最大连续长度,代码中有注释,下面的代码是AC的)

import sys
# 测试用例数量
n_sample=int(sys.stdin.readline().strip())

for i in range(n_sample):
    # 视频帧数
    n_frame=int(sys.stdin.readline().strip())
    # 所有帧的特征向量
    all_p_vectors=[]
    for p in range(n_frame):
        # 特征数量和具体特征
        row_input=map(int,sys.stdin.readline().strip().split())
        # 特征数量
        n_vector=row_input[0]
        v_x=row_input[1:][::2]
        v_y=row_input[2:][::2]
        # 特征
        vectors=zip(v_x,v_y)
        all_p_vectors.append(vectors)
        # print vectors

    # 接下来需要找到最长的特征向量
    # 考虑bfs,从当前帧的某一个特征向量开始,判断下一帧是否有同样的特征向量

    # 从当前帧开始的最大长度
    # 计算从p帧开始的v的最大长度
    def get_max_cont_l(p,v):
        cnt=1
        all_p=all_p_vectors[p+1:]
        for each_p in all_p:
            if v in each_p:
                cnt+=1
            else:
                break
        return cnt
    p=0
    max_l=0

    for p in range(n_frame):
        for v in all_p_vectors[p]:
            cur_l=get_max_cont_l(p,v)
            if cur_l>max_l:
                max_l=cur_l

    print max_l

第三题:

题目描述:

是一个跳塔游戏:说是有N+1个塔,编号为0,1,...,N。假设编号为i的塔的高度为H(i),塔0的高度为0。跳塔规则是:假设当前能量为E,所在的塔为(i-1),如果要E>=H(i),那么跳到塔i上时能量增加E-H(i);如果E<H(i),那么跳到塔i上时能量减少H(i)-E。玩游戏的过程中能量不能为负值。

输入是N和塔1到塔N的高度H(i),要求输出最小的初始能量。

思路:从给出的H(i)的最小值到最大值作为初始值遍历,一旦满足要求就输出即可。

代码:(已AC)

import sys
def getResult(InitE):
    E=InitE
    for i in HList:
        if E<i:
            E=E-(i-E)
        else:
            E+=(E-i)
        if E<0:
            return False
        else:
            continue
    return True

N=int(sys.stdin.readline().strip())
HList=list(map(int,sys.stdin.readline().strip().split()))
MinH=min(HList)
MaxH=max(HList)
for i in range(MinH,MaxH+1):
    if getResult(i)==True:
        print(i)
        break
    else:
        continue

第四题:

题目描述
小明目前在做一份毕业旅行的规划。打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次。 由于经费有限,希望能够通过合理的路线安排尽可能的省些路上的花销。给定一组城市和每对城市之间的火车票的价钱,找到每个城市只访问一次并返回起点的最小车费花销。

输入描述:

城市个数n(1<n<=20,包括北京)

城市间的车票价钱n行n列的矩阵 m[n][n]

输出描述:

最小车费花销s

实例1:

4

0 2 6 5

2 0 4 4

6 4 0 2

5 4 2 0

输出

13
思路:这个旅行商问题,是一个NP难问题,别人用动态规划解决的思路如下:

https://www.cnblogs.com/youmuchen/p/6879579.html

代码中需要求解某集合的所有子集,用函数subsets()求解,也是参考别人的思路:

https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51604217

代码如下:

import sys
import copy


def subsets(nums):#f返回某个列表(集合)的所有子集
    res = [[]]
    for num in nums:
        for temp in res[:]:
            x = temp[:]
            x.append(num)
            res.append(x)
    return res

#读入城市数量和城市之间的花费
CityNumber=int(sys.stdin.readline().strip())
CostList=[]
for i in range(CityNumber):
    CostList.append(list(map(int,sys.stdin.readline().strip().split())))

#CostDict存储动态规划需要的表,表的每一行对应每隔一城市0,1,2,...,CityNumber-1
CostDict={}
CityNumber_subsets=subsets(list(range(1,CityNumber)))
for j in CityNumber_subsets:
    for i in range(0,CityNumber):
        if j==[]:
            CostDict[(i,tuple(j))]=CostList[i][0]
        else:
            CostDict_values=[]
            for j_sub in j:
                j_temp=copy.deepcopy(j)
                j_temp.remove(j_sub)
                CostDict_values.append(CostList[i][j_sub]+CostDict[(i,tuple(j_temp))])
            CostDict[(i, tuple(j))]=min(CostDict_values)
print(CostDict[(0, tuple(list(range(1,CityNumber))))])

第五题:

题目描述:

有n个人要过河,但是河边只有一艘船;

船每次最多坐三个人,每个人单独坐船过河的时间为a[i];

两个人或者三个人一起坐船时,过河时间为他们所有人中的最长过河时间;

为了安全起见,要求每次至少有两个人才能过河。

问最短需要多少时间,才能把所有人送过河。

输入描述:

第一行是整数n,表示测试样例格式

每个测试样例的第一行是一个正整数n,表示参加过河的人数(2<=n<100000)

第二行是n个正整数a[i](0<a[i]<100000),表示n个人单独过河的时间;

输出描述

对每个测试样例,输出应该准备的最少的过河时间

示例1:

输入:

2

2

1 2

1 1 1 1

输出

2

3

解答待更新

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

skj1995

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值