以下解答是我自己的解法,有待优化,仅供参考!
第一题:.
题目描述
公司的程序员不够用了,决定把产品经理都转变为程序员以解决开发时间长的问题。
在给定的矩形网格中,每个单元格可以有以下三个值之一:
.值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.youkuaiyun.com/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
4
1 1 1 1
输出
2
3
解答待更新