准备
python从键盘读取数据
# InputContent就是你在键盘输入的内容,直到你按下enter(回车)键。
InputContent = input('这里写提示语句')
# 注意,这个InputContent是一个String,就是字符串,我们首先需要按照我们输入时候规定的间隔符将有效信息按
# 照分隔符分隔出来。因此,首先要用到split函数。分隔之后就是把你输入的字符串按照分隔符划分得到的一个List。
# 注意,这个List中的每个元素是一个单独的char(单字符)。
# 因此如果你想要得到其中的数字,就还需要进行字符解析,就是把'5'转成5,前者只是一个字符,后者才是数据。
List = InputContent.split('分隔符')
# 利用map(eval, List)对List中的每个元素进行解析,得到与其相等(eval)的值。
# map函数返回的不是list类型的对象,所以这里需要在外面套上一个list()进行强制类型转换。
List = list(map(eval, List))
找出一个list中最大的前n个数
import heapq
heapq.nlargest(n,List)
python运算符
//表示整除
%表示取余
**表示幂运算,例如2的5次方就是2**5
两个list拼接
A = [1,2]
B = [3,4]
# 将A和B按照A前B后的顺序拼接成一个list,拼接结果保留在A中。这个方法没有返回值,之后直接使用A即可。
A.extend(B)
list排序
List.sort()# 默认是升序,如果你设置参数reverse = True就是降序排序。
list切段
# 将List从下标i出切断,List[i]不要了。
List[i+1:]
List[:i]
找子序列
思路:对于一个给定序列,要找其子序列,就是用两个下标指针,一个start作为子序列开始位置下标,另一个end作为子序列结束位置的下标。end从左往右滑动,这是外层循环;每次end确定时,start从左向右滑动到end处,这是内层循环。这样每一对[start,end)之间的子序列就得到了。这样当两层循环执行完,就可以得到给定序列的所有子序列。
Subs = []
for end in range(1,len(List)+1):
for start in range(end):
#print('start = {0}, end = {1}'.format(start,end))
Subs.append(List[start:end])
生成一个给定规则的list
# 构造一个list名叫NewList,其中每个元素都是从老list也就是OldList中复制过来的,且只复制大于零的元素。
NewList = [a for a in OldList and a > 0]
# 注意,这里NewList的元素应当是List[i] > List[i+1]这个判断语句的结果,也就是True或者False。
NewList = [List[i] > List[i+1] for i in range(len(List)-1)]
判断一个list中所有元素是否都是True
all(List)
代码
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 14 14:35:47 2020
@author: Administrator
"""
import numpy as np
import heapq
def ZhaYinHua():
# 扎银花
numPai = int(input('请输入各自牌数n:'))
if numPai < 0 or numPai > 20000:
print('n范围超界,程序结束。')
return
Alist = input('请输入第一个人的牌组,用英文逗号分隔:')
Blist = input('请输入第二个人的牌组,用英文逗号分隔:')
# 将读取到的字符串按照英文逗号分割称一个列表,并将列表中的单个字符一个个的转成对应的数字。
Alist = list(map(eval,Alist.split(',')))
Blist = list(map(eval,Blist.split(',')))
#print(heapq.nlargest(3, Alist))
sumA = sum(heapq.nlargest(3, Alist))
sumB = sum(heapq.nlargest(3, Blist))
if sumA > sumB:
print('第一个人获胜,最大和为{}'.format(sumA))
elif sumA < sumB:
print('第二个人获胜,最大和为{}'.format(sumB))
else:
print('平局,最大和为{}'.format(sumB))
def MaxScore():
# 最大化得分
InputList1 = input('请输入任务数n,每个任务的子任务数k和时间m,用英文逗号分隔:')
InputList1 = list(map(eval, InputList1.split(',')))
numTask = InputList1[0]
numSubTask = InputList1[1]
Time = InputList1[2]
if numTask < 1 or numTask > 100 or numSubTask < 0 or numSubTask > 100 or Time < 0 or Time > 2*(10**9):
print('范围超界,程序结束。')
return
InputList2 = input('请输入子任务奖励分p和任务额外奖励分q,用英文逗号分隔:')
InputList2 = list(map(eval,InputList2.split(',')))
SubScore, ExtraScore = InputList2[0], InputList2[1]
if SubScore < 1 or SubScore > 100 or ExtraScore < 1 or ExtraScore > 100:
print('范围超界,程序结束。')
return
SubTimeK = input('请输入k个子任务完成所需时间,用英文逗号分隔:')
SubTimeK = list(map(eval,SubTimeK.split(',')))
SubTimeK.sort()
for ti in SubTimeK:
if ti < 1 or ti > 10**6:
print('范围超界,程序结束。')
return
# 先计算一下可以完成几个任务以尽可能多的获取额外加分
TaskTime = sum(SubTimeK)
numTaskFinished = Time // TaskTime
MaxScore = 0
if numTaskFinished == 0:
# 如果全部的时间也不够完成一个完整的任务,就按照时间越短的先做。
for ti in SubTimeK:
if Time < ti:
break
T = numTask * ti
if T > Time:
num_now = Time // ti
MaxScore = MaxScore + SubScore * num_now
Time = Time % ti
else:
MaxScore = MaxScore + SubScore * numTask
Time = Time - T
else:
# 如果能完成至少一个任务,则将剩下的时间用于做剩下任务,且时间消耗少的先做。
MaxScore = MaxScore + SubScore * numTaskFinished * numSubTask + ExtraScore * numTaskFinished
Time = Time - numTaskFinished * TaskTime
for ti in SubTimeK:
if Time < ti:
break
T = numTask * ti
if T > Time:
num_now = Time // ti
MaxScore = MaxScore + SubScore * num_now
Time = Time % ti
else:
MaxScore = MaxScore + SubScore * numTask
Time = Time - T
print('最大得分:{}'.format(MaxScore))
def MaxLenUpSubString():
# 最长上升子串
n = int(input('请输入正整数序列的长度n:'))
if n < 0 or n >100000:
print('范围超界,程序结束。')
return
List = input('请输入正整数序列,用英文逗号分隔:')
List = list(map(eval, List.split(',')))
for a in List:
if a < 1 or a > 100000:
print('范围超界,程序结束。')
return
# 只有删除重复元素得到的子串才可能是最长的
LongestLength = 0
for DelIdx in range(len(List)):
New_List = List[:DelIdx]
New_List.extend(List[DelIdx+1:])
print(New_List)
Len = FindLongestUpSubList(New_List)
if LongestLength < Len:
LongestLength = Len
print('最长上升字串长度为{}'.format(LongestLength))
def FindLongestUpSubList(List):
Subs = []
for end in range(1,len(List)+1):
for start in range(end):
#print('start = {0}, end = {1}'.format(start,end))
Subs.append(List[start:end])
#print('子串有:{}'.format(Subs))
LengthMax = 0
LenMaxSub = []
# 检查Subs中每个Sub的递增性,并记录最长长度
for Sub in Subs:
if all([Sub[i] < Sub[i+1] for i in range(len(Sub)-1)]):
if LengthMax < len(Sub):
LengthMax = len(Sub)
LenMaxSub = Sub
return LengthMax
def RunPlan():
# 跑步计划
InputList = input('请输入图中的点数n,边数m和起点编号s,用英文逗号分隔:')
InputList = list(map(eval, InputList.split(',')))
NodeNum, EdgeNum, StartId = InputList[0], InputList[1], InputList[2]
if NodeNum < 0 or NodeNum > 100000 or EdgeNum < 0 or EdgeNum > 100000:
print('范围超界,程序结束。')
return
InputEdges = []
for i in range(EdgeNum):
InputOneEdge = input('请输入图中的一条边的起点编号,终点编号和边的权重,用英文逗号分隔:')
InputOneEdge = list(map(eval, InputOneEdge.split(',')))
if InputOneEdge[2] <0 or InputOneEdge[2] > 1000 or InputOneEdge[0] < 1 or InputOneEdge[0] > NodeNum or InputOneEdge[1] < 1 or InputOneEdge[1] > NodeNum:
print('范围超界,程序结束。')
return
# 将编号转成从0开始
for i in range(len(InputOneEdge)-1):
InputOneEdge[i] = InputOneEdge[i] - 1
InputEdges.append(InputOneEdge)
RunDst = int(input('请输入希望跑步的距离k:'))
if RunDst < 1 or RunDst > 10**9:
print('范围超界,程序结束。')
return
NeighborMat = np.zeros((EdgeNum,EdgeNum))
for e in InputEdges:
NeighborMat[e[0]][e[1]] = e[2]
NeighborMat = np.mat(NeighborMat)
for e in InputEdges:
NeighborMat[e[0],e[1]] = e[2]
NeighborMat = NeighborMat + NeighborMat.T
NeighborMat = np.array(NeighborMat)
print(NeighborMat)
NodeNote = set()
EdgeNote = set()
'''
while dst <:
for j in range(len(NeighborMat[0])):
if j in NodeNote or (i,j) in EdgeNote:
continue
i = j
'''
'''
RowMat = NeighborMat[StartId-1]
Result = []
Result.append(np.array(RowMat))
for i in range(RunDst-1):
RowMat = np.dot(RowMat,NeighborMat)
Result.append(np.array(RowMat))
# Result中依次存储的是从startId开始,1到k阶的可达点。
# 检查Result中k阶可达点,并检查这些点是否在k阶以前就可达,若是则不要,反之则保留。
print(Result)
#print(np.array(Result[-1])[0])
ShortK = []
for k in range(1,len(Result[-1][0])):
print(Result[-1][0][k])
flag = 0
if Result[-1][0][k] != 0:
for attachi in range(len(Result)-1):
if Result[attachi][0][k] != 0:
flag = 1
break
if flag == 1:
# 出现了不是最短距离的k阶可达点
continue
else:
# 这个点是k阶最短距离可达点
ShortK.append(k)
print('最短可达目的地个数为:{}'.format(len(ShortK)))
'''
dst, path = dijkstra(NeighborMat, StartId-1)
print(dst)
def dijkstra(graph,src):
# 定点集合
nodes = [i for i in range(len(graph))] # 获取顶点列表,用邻接矩阵存储图
# 顶点是否被访问
visited = []
visited.append(src)
# 初始化dis
dis = {src:0}# 源点到自身的距离为0
for i in nodes:
dis[i] = graph[src][i]
path={src:{src:[]}} # 记录源节点到每个节点的路径
k=pre=src
while nodes:
temp_k = k
mid_distance=float('inf') # 设置中间距离无穷大
for v in visited:
for d in nodes:
if graph[src][v] != float('inf') and graph[v][d] != float('inf'):# 有边
new_distance = graph[src][v]+graph[v][d]
if new_distance <= mid_distance:
mid_distance=new_distance
graph[src][d]=new_distance # 进行距离更新
k=d
pre=v
if k!=src and temp_k==k:
break
dis[k]=mid_distance # 最短路径
path[src][k]=[i for i in path[src][pre]]
path[src][k].append(k)
visited.append(k)
nodes.remove(k)
#print(nodes)
return dis,path
def SpecialList():
# 特殊的序列
InputList = input('请输入序列长度n和询问次数m,用英文逗号分隔:')
InputList = list(map(eval, InputList.split(',')))
Length, QueryNum = InputList[0], InputList[1]
if Length < 1 or Length > 100000 or QueryNum < 1 or QueryNum > 100000:
print('范围超界,程序结束。')
return
InitialList = list(input('请输入序列,无分隔符:'))
print('InitialList:{}'.format(InitialList))
for i in range(QueryNum):
S = input('请输入询问,c开头表示0和1的对换,q开头表示求当前整段序列的最长不下降子序列长度,用英文逗号分隔:')
S = S.split(',')
if S[0] == 'c':# 输入的下标从1开始,要转为从0开始。
startid = int(S[1]) - 1
endid = int(S[2]) - 1
for i in range(startid, endid+1):
if InitialList[i] == '0':
InitialList[i] = '1'
else:
InitialList[i] = '0'
Str = ''
for a in InitialList:
Str = Str + a
print('当前序列为:{}'.format(Str))
elif S[0] == 'q':
MaxNoDownSub = FindLongestNoDownSubList(InitialList)
Str = ''
for a in MaxNoDownSub:
Str = Str + a
print('当前最长的不下降子序列为:{}'.format(Str))
else:
print('无效的询问方式!程序结束。')
return
def FindLongestNoDownSubList(List):
# 求List的最长上升子串
# 先求所有子序列
Subs = []
for end in range(1,len(List)+1):
for start in range(end):
#print('start = {0}, end = {1}'.format(start,end))
Subs.append(List[start:end])
#print('子串有:{}'.format(Subs))
LengthMax = 0
LenMaxSub = []
# 检查Subs中每个Sub的递增性,并记录最长长度
for Sub in Subs:
if all([Sub[i] <= Sub[i+1] for i in range(len(Sub)-1)]):
if LengthMax < len(Sub):
LengthMax = len(Sub)
LenMaxSub = Sub
return LenMaxSub