常用的方法

做完之后输出的答案是什么类型需要注意,最好不要循环输出(因为小心最后一个数,不能有空格)

list1 = list(map(int,input().split()));

最后记得根据列表,字典,元组来分类方法

到时候用记事本,tab提示补全

2019,2020所有题,201809,201709第二题

如果出现key可以, key=lambda x:x[1],1可以变,看元组内每个元素里面有几个元素(2,3,3,…)

同时输入多个数字

#2. 同时输入多个数值,字符串间以空格间隔
a,b,c=map(eval,input('同时输入2个数字,以空格间隔:').split())
print(a,b,c);

输入str,可以用for拆分其中的数字

n = input()
sum=0
for i in n:
    sum=sum+int(i)
print(sum)

1、直接创建列表(不理大小,不用循环赋值)

nums = list(map(int,input.split(' ')))

print(nums)

结果:
在这里插入图片描述

2、去除重复set

list1=[1,2,3,4,4];
a = set(list1);
print(a);

结果:
在这里插入图片描述
3、排序,sort,sorted(sorted可以赋值给其他变量,sort不行)

list1=[4,1,3,2];
list1.sort()
print(list1);

结果:
在这里插入图片描述

s = [32,453,643,7,0,403,45,0,422,654,4,43,0,53];
s1 = set(s);		#set是去重,不会根据顺序去重的,所以在set后排序
dict1 = {};			#定义一个字典,并且赋值
for i in s1:
    dict1[i] = s.count(i);

print(dict1);
print("\n看一下dict1.items()是怎么样的",dict1.items(),"\n");		#.items()是元组的意思

maxnum = max(dict1.items(),key=lambda x:x[1]);	#这里表示用元组的形式比较,找出所有第二位最大的值
print(maxnum[0]);
d_order = sorted(dict1.items(),key=lambda x:x[0], reverse=True);
print(d_order);

4、查长度,len

list1=[4,1,3,2];
list1.sort()
print(len(list1));

结果:
在这里插入图片描述

5、append

list1 = [123, 'xyz', 'zara', 'abc'];
list1.append( 2009 );
print(list1);

结果:
在这里插入图片描述

6、count

list1 = [32,543,6543,654,645,0,0,0];
n = list1.count(0);
print(n);

结果:
在这里插入图片描述

7、max

list1 = [32,543,6543,654,645,0,0,0];
n = max(list1);
print(n);

在这里插入图片描述

8、查找元素位置,index

aList = [123, 'xyz', 'runoob', 'abc']

print "xyz 索引位置: ", aList.index( 'xyz' )

在这里插入图片描述

9、输出时用空格间隔,print(1, end=’ ')

list1 = [32,543,6543,654,645,0,0,0];
for i in list1:
    print(i,end=' ');

在这里插入图片描述

10、查数字

#上面两个例子0是作为元素去查询,如果只有 304 这样的元素里面有0,也是查不到的
list1 = [321,354,764,5,87,3,0,25];
if(0 in list1):
    print("里面有0存在");
else:
    print("里面没有0存在");

list1 = ["321","354","764","5","87","3","0","25"];
if("0" in list1):
    print("里面有0存在");
else:
    print("里面没有0存在");

list1 = "423423";
if("0" in list1):
    print("里面有0存在");
else:
    print("里面没有0存在");

11、返回元素的位置

#列表中最好用index,别用find(find只可以用在字符串上)
s = [32,453,603,7,0,423,45,0,422,654,4,43,0,53];
count = s.count(0);
s1 = str(s);
print(s1);
# print(type(s1));
n=0;
for i in range(count):

    print("0在列表中第",s.index(0,n));     # 这里的n表示从第n位开始查找
    n = s.index(0,n) +1;

结果:

加粗样式

12、可能会用到的换行,还有结束时用空格隔开


s = [32,453,643,7,0,403,45,0,422,654,4,43,0,53];
#给我输出每个元素出现的次数
for i in s:
    print("thank u",end=" ");

print();    #这里用这句话来换行,别用\n否则行距会变得很大

n = len(s);
for i in range(n):
    print("thank u", end=" ");

结果:
在这里插入图片描述
13、删除列表元素,del

list2 = [343,43,453,23];
del list2[0];
print(list2);

结果:
在这里插入图片描述
13、删除列表元素,pop(可以赋值 )

list1 = ['Google', 'Runoob', 'Taobao']
list_pop=list1.pop(1)
print "删除的项为 :", list_pop
print "列表现在为 : ", list1

结果:
在这里插入图片描述

14、扭转二维数组:
在这里插入图片描述

m,n = list(map(int,input().split()))        #定义m行,n列
numbersarray = []
for i in range(0, m):                       #在列表中再加m行列表,变成矩阵
    numbersarray.append(list(map(int, input().split())))
# print(numbersarray)
for x in range(n-1,-1,-1):                  #2、一共有多少行
    for y in range(0, m):                   #1、每行先输出m个元素
        print(numbersarray[y][x],end=' ')
    print()

结果:
在这里插入图片描述
15、二维数组初始化:

m,n = map(int,input().split());

list1 = [];
list2 = [];
for i in range(n):
    list2.append(0);

for i in range(m):
    list1.append(list2);

print(list2);
print(list1);

结果:
在这里插入图片描述
16、次方还有根号(**2,**0.5)

17、字符串切片

s = '0-670-82162-4';
print(s);
print(s[0:-1]);

print('如果想要输出0-670-82162-X');
print(s[0:-1],end='')
print('X');

结果:
在这里插入图片描述

这里需要注意,字符串不可改变,只能用列表方式改变,或者用切片先不输出

18、列表反过来排列
(1)

list2 = [];
list_temp = [];

for i in range(n):
    list1 = list(map(int,input().split()));
    list2.append(list1);

for i in range(-1,-n-1,-1):             #反过来排序
    list_temp.append(list2[i][:]);
print(list2);
print(list_temp);

结果:
在这里插入图片描述
(2)

li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
print(li[::-1])

结果:
在这里插入图片描述

19、二维列表中换位

list2 = [[0, 0, 4, 4], [1, 1, 5, 5], [2, 2, 6, 6]];

list2[0][:],list2[2][:] = list2[2][:],list2[0][:];
print(list2);

结果:
在这里插入图片描述
20、从判断跳出循环(201403-2)

for i in range(3):
    result = 0;
    for j in range(2):
        print(j,end=' ');               #若只有这里,要输出3次 0 1
        if(j ==1):
            result=1;
            break;                      #这里的break,只是跳出这个判断而已
    if(result==1):                      #这里的break,已经是跳出了最上面的循环,也就是所有循环,所以输出1次 0 1
        break;

结果:
在这里插入图片描述

21、replace和eval,字符直接计算



def st190302():
    n=int(input())
    for i in range(n):
        a = input().replace('/','//').replace('x', '*')
        num=eval(a)
        if num==24:
            print('Yes')
        else:
            print('No')

if __name__ == '__main__':
    st190302()

22、字典中get函数

dict = {'Name': 'Runoob', 'Age': 27}

print "Value : %s" %  dict.get('Age')

结果:
在这里插入图片描述

23、两个列表找相同元素

print(set(a) & set(b))

24、两个列表切片合并成一个列表


#方法一
list1 = [1,2,3,4,5];
list2 = [6,7,8,9,10];
list3 =[];
list3.append(list1[0:3]+list2[2:4]);
print(list3)

#结果:[[1, 2, 3, 8, 9]]

#方法二:
list1 = [1,2,3,4,5];
list2 = [6,7,8,9,10];
list3 =[];
list3.append([list1[0:3],list2[2:4]]);
print(list3)
#结果:[[[1, 2, 3], [8, 9]]]

25、多维列表降维
https://blog.csdn.net/weixin_39564036/article/details/111286230

第二题

二维前缀和必须是正方形矩阵即:n*n;若是后缀和反过来加0
4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16


n=int(input())
a=[]
count=0
for i in range(n):
    a.append(list(map(int,input().split())))
for i in range(n):
    a[i].insert(0,0)                        #先给每一行加0
a.insert(0,[0]*(n+1))                       #直接加入一行0
print(a)
S=[([0]*(n+1))for i in range(n+1)]          #初始化数组
print(S)
for i in range(1,n+1):
    for j in range(1,n+1):
        Sum=0
        Sum+=a[i][j]+S[i-1][j]+S[i][j-1]-S[i-1][j-1]
        S[i][j]=Sum


print(S)
for i in range(n+1):
    S[i].remove(0)
del S[0];
print(S)

map用于存储稀疏数据是最有效的,也可以用来存储稀疏向量。2个向量不必都存储,能够边读入数据边计算可以节省存储,也有助于提高计算速度。等于字典

优先队列:就像字典排序

贪心法:就像找零一样

第三题:字符串

第四题:算法题

BFS(广度优先搜索)和DFS(深度优先搜索):
https://blog.csdn.net/marxoffice/article/details/97501536
https://developer.51cto.com/art/202004/614590.htm

graph = {
‘A’: [‘B’, ‘C’],
‘B’: [‘A’, ‘C’, ‘D’],
‘C’: [‘A’, ‘B’, ‘D’, ‘E’],
‘D’: [‘B’, ‘C’, ‘E’, ‘F’],
‘E’: [‘C’, ‘D’],
‘F’: [‘D’]
}

def BFS(graph, node):
    queue = []#BFS使用栈实现先进先出
    queue.append(node)
    searched = set()
    searched.add(node)
    while(len(queue) > 0):
        vertex = queue.pop(0)
        nodes = graph[vertex]
        for node in nodes:
            if node not in searched:
                queue.append(node)
                searched.add(node)
        print(vertex)
def DFS(graph, node):    
    stack = []#DFS使用栈实现先进后出
    stack.append(node)
    searched = set()
    searched.add(node)
    while(len(stack) > 0):
        vertex = stack.pop()
        nodes = graph[vertex]
        for node in nodes:
            if node not in searched:
                stack.append(node)
                searched.add(node)
        print(vertex)

用Kruskal算法实现。有关最小生成树的问题,使用克鲁斯卡尔算法更具有优势,
https://blog.csdn.net/weixin_44193909/article/details/88774567

graph = {
        'vertices':['A', 'B', 'C', 'D'],
        'edges':[
                (1, 'A', 'B'),
                (5, 'A', 'C'),
                (3, 'A', 'D'),
                (4, 'B', 'C'),
                (2, 'B', 'D'),
                (1, 'C', 'D'),
                ]
        }
edges=graph['edges']
edges.sort()
vertices=graph['vertices']
trees=[]
direction={}
for vertice in vertices:
    direction[vertice]=-1
for edge in edges:
    vertice_1=edge[1]
    vertice_2=edge[2]
    index_1=direction[vertice_1]
    index_2=direction[vertice_2]
    if index_1<0 and index_2<0:
        direction[vertice_1]=len(trees)
        direction[vertice_2]=len(trees)
        trees.append([edge])
    else:
        if index_1<0:
            direction[vertice_1]=index_2
            trees[index_2].append(edge)
        if index_2<0:
            direction[vertice_2]=index_1
            trees[index_1].append(edge)
    if not (index_1<0 or index_2<0):
        if trees[index_1]!=trees[index_2]:
            new_tree=trees[index_1]+[edge]+trees[index_2]
            trees[index_1]=new_tree
            trees[index_2]=new_tree
print(trees[0]) 

这是一个强联通图的问题,用Tarjan算法来解决。另外一个算法是kosaraju算法,也用于解决强联通图问题(点点互通,找关键点可以把整个树刚好一分为二)

class HashTable:  # 边表
    def __init__(self, edges: list, undirected: bool, n: int):
        self.hash_map = {}
        for i in range(n):
            self.hash_map.setdefault(i, set())
        for edge in edges:
            self.hash_map[edge[0]].add(edge[1])
            if (undirected):  # 无向图
                self.hash_map[edge[1]].add(edge[0])


class Tarjan:
    # 强连通分量Strong Connected Component,简称SCC
    # 割点/边问题Cut Point/Edge
    def __init__(self, n: int, edges: list):
        self.n = n
        self.edges = [None, None, None]
        self.edges[1] = HashTable(edges, False, n)
        self.edges[2] = HashTable(edges, True, n)
        self.stack = []
        self.dfn = [0 for _ in range(self.n)]
        self.low = [0 for _ in range(self.n)]
        self.index = 0
        self.answer_set = []  # 最终的SCC群
        self.answer_point = set()  # 最终的割点
        self.answer_edge = set()  # 最终的割边
        self.mode = 0  # 为了方便对照,两个问题使用mode变量区分,1为SCC,2为割点边

    def reload(self): # 重置
        self.stack = []
        self.dfn = [0 for _ in range(self.n)]
        self.low = [0 for _ in range(self.n)]
        self.index = 0
        self.answer_set = []
        self.answer_point = set()
        self.answer_edge = set()

    def scc(self):  # 强连通分量
        self.mode = 1
        for i in range(self.n):  # 防止漏点
            if (self.dfn[i]):
                continue
            self.targan(i, i)

    def cut_point_and_cut_edge(self):  # 割点/边问题
        self.mode = 2
        for i in range(self.n):  # 防止漏点(其实这是句废话,初始图不是连通的是啥情况?)
            if (self.dfn[i]):
                continue
            self.targan(i, i)

    def targan(self, now: int, father: int):
        self.index += 1  # 访问时间戳加1
        self.dfn[now] = self.low[now] = self.index  # 初始化当前节点的DFN和LOW

        if (self.mode == 1):
            self.stack.append(now)  # 压栈

        child_cnt = 0
        for i in self.edges[self.mode].hash_map[now]:  # 枚举边所能到的点
            if (self.dfn[i]):  # 已经被处理过
                if (i in self.stack and self.mode == 1):  # 如果i在栈内,now点能到达的最小时间戳是它自己能到达点的最小时间戳和i的时间戳的min
                    self.low[now] = min(self.low[now], self.dfn[i])
                    # 关于为什么是dfn[i],这是因为low[i]可能被搜索树的其它子树更新过了,而
                    # dfn[i]并不会改变,在强连通分量里,这里改成now[i]没有任何问题,因为强连通分量只关注是不是同一个连通集合,但割点问题不行!
                    # 割点问题关心的是子树而不是集合,如果改成low[i]会导致子树的low和父树的low一致,导致子树合二为一,从而使得原本子树多于2的子节点无法被找到,从而出现遗漏

                if (self.mode == 2):
                    if (i == father):  # 注意不能回头
                        continue
                    self.low[now] = min(self.low[now], self.dfn[i])

            else:  # 没被处理过
                child_cnt += 1
                self.targan(i, now)  # DFS的本质
                self.low[now] = min(self.low[now], self.low[i])

        if (self.mode == 1):
            # 所有的边都访问过后,检查是否为强连通分量根节点(low == dfn)
            if (self.low[now] == self.dfn[now]):
                scc = set()
                while (self.stack[-1] != now):  # 开始弹栈
                    scc.add(self.stack.pop())
                scc.add(self.stack.pop())  # 不要忘记了它自己
                self.answer_set.append(scc)

        if (self.mode == 2):
            # 所有的边都访问过后,检查周围是否有low[i] > dfn[now]
            if (child_cnt >= 2 and father == now):  # 是根且子树多于2个,有割点没割边
                self.answer_point.add(now)
            for i in self.edges[self.mode].hash_map[now]:
                if (self.low[i] >= self.dfn[now] and father != now): # 有割点没割边 注意不能是根节点
                    self.answer_point.add(now)
                    if (self.low[i] > self.dfn[now]):
                        self.answer_edge.add((now, i))



if __name__ == '__main__':
    edges = [[0, 2], [2, 1], [1, 0], [2, 3], [3, 4], [4, 5], [3, 6], [6, 2], [2, 7], [7, 6]]
    #edges = [[0, 1], [1, 2], [2, 3], [1, 4], [4, 0], [0, 5], [5, 4], [0, 6], [6, 7], [7, 0]]
    test = Tarjan(8, edges)
    # 强连通分量
    test.scc()
    print("强连通分量个数:", len(test.answer_set), "\n所有的强连通分量:", test.answer_set, "\n")

    test.reload()
    # 割点/边问题
    test.cut_point_and_cut_edge()
    print("割点集合:", test.answer_point, "\n割边集合:", test.answer_edge)

欧拉路径
https://shentuzhigang.blog.csdn.net/article/details/88553573?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

# 路线图
# 假设:a,b,c,d,e,f,g,h,k,k,l,m 这13个点的代号为0,1,2,3,4,5,6,7,8,9,10,11,12
eulerEdges = [
    (0, 2),(0, 1),(0, 3),(0, 4),(1, 2),
    (1, 3),(1, 5),(6, 2),(3, 5),(4, 5),
    (4, 7),(4 ,10),(5, 6),(5, 8),(5, 11),
    (6, 9),(6, 12),(7, 10),(7, 11),(8, 9),
    (8, 11),(9, 11),(9, 12),(10, 11),(11, 12)
]#  这个列表里的25个元素均代表一条路径
# 可以通过修改start的值来确定起始位置
start = 3    # 检查员起始位置,笔者认为从效率考虑,应该从d点开始检查
visited = [0 for i in range(len(eulerEdges))] #访问过的路
queue = [] # 保存路径信息
# print(queue)
eulerFlag = False

def isEuler():
    allVisited = True
    for e in visited:
        if e == 0:
            allVisited = False
    if allVisited:
        if queue[0] == queue[len(queue) - 1]:
            return 1
        else:
            return 2
    return 0

def printPath(flag):
    if flag == 1:
        print("是欧拉回路:", end="")
    else:
        print("是欧拉道路:", end="")
    for i in range(len(queue)):
        if i < len(queue) - 1:
            print(queue[i], "-> ", end="")
        else:
            print(queue[i])

# 搜索过程只保存一条路的状态的信息,且不重复经过某一路线
def dfs(u):
    li = queue.append(u)
    flag = isEuler()  # 判断当前路径是不是欧拉路,如果是则打印
    if flag > 0:
        eulerFlag = True
        printPath(flag)
    for i in range(len(eulerEdges)):
        if visited[i] == 1:
            continue
        edge = eulerEdges[i]
        if edge[0] == u:
            visited[i] = 1
            dfs(edge[1])
            #queue.pop()     # 将搜索过的点弹出队列
            # visited[i] = 0  # 重置访问状态
        elif edge[1] == u:
            visited[i] = 1
            dfs(edge[0])
            #queue.pop()     # 将搜索过的点弹出队列
            # visited[i] = 0  # 重置访问状态
dfs(start)
# if not eulerFlag:  # 判断另一种情况
#     print("否则:不是欧拉回路或欧拉道路")

这是一个最优化的问题,也是一个单源最短路径问题,所有要用Dijkstra算法
https://blog.csdn.net/weixin_41971381/article/details/104747600?utm_term=dijkstra%E7%AE%97%E6%B3%95python3&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-5-104747600&spm=3001.4430

def dijkstra(graph):
    l = len(graph)
    visit = [i for i in range(6)]  # 未遍历点
    current = visit[0]  # 当前遍历点
    path = {}  # 最短路径
    res = {}  # 最短距离
    # 0到各个点的初始值
    for i in range(l):
        res[i] = graph[0][i]
        path[i] = '0->{}'.format(i)
    while visit:
        dtmp = []  # 每次遍历,把当前点到其它点的距离用一个列表按顺序储存起来
        for i in range(l):
            if current != i:
                # 松弛操作
                if (res[current] + graph[current][i]) < res[i]:
                    res[i] = res[current] + graph[current][i]
                    path[i] = path[current] + '->{}'.format(i)
                # 记录当前点到周围点的距离,并排序
                if not dtmp:
                    dtmp.append([i, graph[current][i]])
                else:
                    f = 0
                    for j in range(len(dtmp)):
                        if graph[current][i] < dtmp[j][1]:
                            dtmp.insert(j, [i, graph[current][i]])
                            f = 1
                            break
                    if f == 0:
                        dtmp.append([i, graph[current][i]])
        for i in dtmp:
            if i[0] not in visit:
                dtmp = dtmp[1:]
            else:
                visit.remove(i[0])
                current = i[0]
                break
        # print(dtmp)
        # print(current,res)
    return res, path


if __name__ == '__main__':
    graph = [[0, 2, 1, 4, 5, 1],
             [1, 0, 4, 2, 3, 4],
             [2, 1, 0, 1, 2, 4],
             [3, 5, 2, 0, 3, 3],
             [2, 4, 3, 4, 0, 1],
             [3, 4, 7, 3, 1, 0]]

    res, path = dijkstra(graph)
    print(res)
    print(path)

第二题

试题编号试题名称算法
202104-2邻域均值二维前缀和
202012-2期末预测之最佳阈值排序、前缀和以及后缀和
202009-2风险人群筛查排序
202006-2稀疏向量map
201912-2回收站选址map、排序
201909-2小明种苹果(续)排序
201903-2二十四点表达式
201812-2小明放学排序、数据类型
201809-2买菜排序
201803-2碰撞的小球排序、模拟
201712-2游戏排序或STL的向量vector或STL的队列queue
201709-2公共钥匙盒优先队列
201703-2学生排队排序或STL的向量vector或STL的list(链表)
201612-2工资计算数据类型
201609-2火车购票map
201604-2俄罗斯方块map
201512-2消除类游戏
201509-2日期计算
201503-2数字排序map、排序
201412-2Z字形扫描
201409-2画图
201403-2窗口
201312-2ISBN号码数据类型

排序、二维前缀和、map、STL的向量vector、STL的队列queue

第四题

试题编号试题名称算法
202104-4校门外的树打表预处理
201612-4压缩编码平行四边形优化
201609-4交通规划Dijkstra算法、邻接表
201604-4游戏BFS
201512-4送货欧拉路径、邻接表、DFS
201509-4高速公路Tarjan算法或kosaraju
201503-4网络延时DFS或BFS
201412-4最优灌溉Kruskal(克鲁斯卡尔)算法或Prim(普里姆) 算法
201409-4最优配餐BFS
201403-4无线网络BFS
201312-4有趣的数DP(动态规划)

打表预处理、平行四边形优化、Dijkstra算法、邻接表、BFS、欧拉路径、DFS、Kruskal(克鲁斯卡尔)算法、Prim(普里姆) 算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值