美团

准备

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运算符

//表示整除
%表示取余
**表示幂运算,例如25次方就是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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值