python蓝桥杯从入门到~

输入与输出

输入

数组输入:
可以提前定义
a = [0 for i in range(1000)]
或者
arr = list(map(int,input().split()))

输出

import math
pi = math.pi
p = -1*pi
print(pi)
print('%.4f' % pi)
# 2,前面补充前导0表示月份
a = 2 # 2月输出02
b = 11 # 11月输出11
print('%02d' % a)
print('%02d' % b)
print('%d %d' % (a,b))

dfs与bfs

X星球的一处迷宫游乐场建在某个小山坡上。
它是由10x10相互连通的小房间组成的。
房间的地板上写着一个很大的字母。
我们假设玩家是面朝上坡的方向站立,则:
L表示走到左边的房间,
R表示走到右边的房间,
U表示走到上坡方向的房间,
D表示走到下坡方向的房间。
X星球的居民有点懒,不愿意费力思考。
他们更喜欢玩运气类的游戏。这个游戏也是如此!
开始的时候,直升机把100名玩家放入一个个小房间内。
玩家一定要按照地上的字母移动。
迷宫地图如下:
UDDLUULRUL

UURLLLRRRU

RRUURLDLRD

RUDDDDUUUU

URUDLLRRUU

DURLRLDLRL

ULLURLLRDU

RDLULLRDDD

UUDDUDUDLL

ULRDLUURRR
# 每个方块有一名玩家
# 大暴力不叫dfs
def dfs(x,y):
    global ans
    while True:
        if x>9 or x<0 or y>9 or y<0:
            ans += 1
            break
        if vis[x][y]==1:
            break
        vis[x][y]=1
        if mp[x][y]=='U':
            x-=1
        elif mp[x][y]=='D':
            x+=1
        elif mp[x][y]=='L':
            y-=1
        elif mp[x][y]=='R':
            y+=1
def init():
    for i in range(10):
        for j in range(10):
            vis[i][j]=0
mp = ['' for i in range(10)]
for i in range(10):
    mp[i] = input()
ans = 0
vis = [[0]*10 for i in range(10)]
for i in range(10):
    for j in range(10):
        init()
        dfs(i,j)
print(ans)
农夫约翰有一片 N∗M 的矩形土地。

最近,由于降雨的原因,部分土地被水淹没了。

现在用一个字符矩阵来表示他的土地。

每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,则用”.”表示。

现在,约翰想知道他的土地中形成了多少片池塘。

每组相连的积水单元格集合可以看作是一片池塘。

每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。

请你输出共有多少片池塘,即矩阵中共有多少片相连的”W”块。

输入格式
第一行包含两个整数 N 和 M。

接下来 N 行,每行包含 M 个字符,字符为”W”或”.”,用以表示矩形土地的积水状况,字符之间没有空格。

输出格式
输出一个整数,表示池塘数目。

数据范围
1≤N,M≤1000
输入样例:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出样例:
3
n,m = list(map(int,input().split()))
mp = ['' for i in range(1000)]
vis = [[0]*1000 for i in range(1000)]
dx=[0,0,1,-1,1,1,-1,-1]
dy=[1,-1,0,0,1,-1,1,-1]
def bfs(x,y):
    q = []
    t = [x,y]
    q.append(t)
    vis[x][y]=1
    while len(q)>0:
        t=q[0]
        q.pop(0)
        for i in range(8):
            tx = dx[i]+t[0]
            ty = dy[i]+t[1]
            if tx>=0 and tx<n and ty>=0 and ty<m and vis[tx][ty]==0 and mp[tx][ty]=='W':
                z = [tx,ty]
                q.append(z)
                vis[tx][ty]=1
for i in range(n):
    mp[i] = input()
ans = 0
for i in range(n):
    for j in range(m):
        if vis[i][j]==0 and mp[i][j]=='W':
            bfs(i,j)
            ans+=1
print(ans)
    
一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 n∗n 的格点组成,每个格点只有2种状态,.#,前者表示可以通行后者表示不能通行。

同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。

如果起点或者终点有一个不能通行(#),则看成无法办到。

注意:A、B不一定是两个不同的点。

输入格式
第1行是测试数据的组数 k,后面跟着 k 组输入。

每组测试数据的第1行是一个正整数 n,表示迷宫的规模是 n∗n 的。

接下来是一个 n∗n 的矩阵,矩阵中的元素为.或者#。

再接下来一行是 4 个整数 ha,la,hb,lb,描述 A 处在第 ha 行, 第 la 列,B 处在第 hb 行, 第 lb 列。

注意到 ha,la,hb,lb 全部是从 0 开始计数的。

输出格式
k行,每行输出对应一个输入。

能办到则输出“YES”,否则输出“NO”。

数据范围
1≤n≤100
输入样例:
2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0
输出样例:
YES
NO
t = int(input())
mp = ['' for i in range(100)]
vis = [[0]*100 for i in range(100)]
dx = [0,0,1,-1]
dy = [1,-1,0,0]
def bfs(x,y):
    k = [x,y]
    q = []
    q.append(k)
    vis[x][y]=1
    while len(q)>0:
        k = q.pop(0)
        if k[0]==ex and k[1]==ey:
            return True
        for i in range(4):
            tx = dx[i]+k[0]
            ty = dy[i]+k[1]
            if tx>=0 and tx<n and ty>=0 and ty<n and vis[tx][ty]==0 and mp[tx][ty]=='.':
                z = [tx,ty]
                # print(z)
                q.append(z)
                vis[tx][ty]=1
    return False
def init(n):
    for i in range(n):
        for j in range(n):
            vis[i][j]=0

for i in range(t):
    n = int(input())
    for i in range(n):
        mp[i] = input()
    x,y,ex,ey = list(map(int,input().split()))
    init(n)
    if bfs(x,y)==True and mp[x][y]!='#':
        print('YES')
    else:
        print('NO')

                
                
                
t = int(input())
mp = ['' for i in range(100)]
vis = [[0]*100 for i in range(100)]
dx = [0,0,1,-1]
dy = [1,-1,0,0]
def dfs(x,y):
    if mp[x][y]=='#':
        return False
    if x==ex and y==ey:
        return True
    vis[x][y]=1
    for i in range(4):
        tx = x+dx[i]
        ty = y+dy[i]
        if tx>=0 and tx<n and ty>=0 and ty<n and vis[tx][ty]==0 and mp[tx][ty]=='.':
            if dfs(tx,ty):
                return True
    return False
def init(n):
    for i in range(n):
        for j in range(n):
            vis[i][j]=0

for i in range(t):
    n = int(input())
    for i in range(n):
        mp[i] = input()
    x,y,ex,ey = list(map(int,input().split()))
    init(n)
    if dfs(x,y)==True:
        print('YES')
    else:
        print('NO')
        
                
                

并查集

问题描述
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?

输入格式
第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
接下来k行,第2+k行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。

格子的编号一行一行,从上到下,从左到右编号。
比如:5 * 4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20

样例输入
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17

样例输出
5

def init(n):
    for i in range(1,n+1):
        f[i]=i
def find(x):
    if f[x]==x:
        return x
    else:
        f[x]=find(f[x])
    return f[x]
def union(x,y):
    a = find(x)
    b = find(y)
    if a!=b:
        f[a]=b
n,m = list(map(int,input().split()))
k = int(input())
f = [0 for i in range(m*n+1)]
l = [0 for i in range(m*n+1)]
init(n*m)
for i in range(k):
    x,y = list(map(int,input().split()))
    union(x,y)
for i in range(1,m*n+1):
    l[find(i)]=1
ans = 0
for i in range(1,m*n+1):
    if l[i]==1:
        ans+=1
print(ans)

哈夫曼树

n = int(input())
a = list(map(int,input().split()))
ans = 0
while len(a)>1:
    a.sort()
    x = a[0]
    a.pop(0)
    y = a[0]
    a.pop(0)
    ans = ans+x+y
    a.append(x+y)
print(ans)

二分

# 二分查询
import bisect
a = [0,1,2,4,6,7,9,10]
# bisect_left查找a数组中第一个大于等于5的数的下标
# bisect_right找a数组中第一个大于4的数的下标
print(bisect.bisect_left(a,5))
print(bisect.bisect_left(a,4))
print(bisect.bisect_right(a,4))
# insort_left
# insort_right

lambda排序

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 名学生发奖学金。

期末,每个学生都有 3 门课的成绩:语文、数学、英语。

先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的 3 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名学生的学号和总分。

注意,在前 5 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。

例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279
5 279
这两行数据的含义是:总分最高的两个同学的学号依次是 7 号、5 号。

这两名同学的总分都是 279(总分等于输入的语文、数学、英语三科成绩之和),但学号为 7 的学生语文成绩更高一些。

如果你的前两名的输出数据是:

5 279
7 279
则按输出错误处理。

输入格式
输入文件包含 n+1:1 行为一个正整数 n,表示该校参加评选的学生人数。

第 2 到 n+1 行,每行有 3 个用空格隔开的数字,每个数字都在 0100 之间,第 j 行的 3 个数字依次表示学号为 j−1 的学生的语文、数学、英语的成绩。

每个学生的学号按照输入顺序编号为 1∼n (恰好是输入数据的行号减 1)。

所给的数据都是正确的,不必检验。

输出格式
输出文件共有 5 行,每行是两个用空格隔开的正整数,依次表示前 5 名学生的学号和总分。

数据范围
6≤n≤300
输入样例:
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
输出样例:
6 265
4 264
3 258
2 244
1 237

n = int(input())
res = []
# chinese math english
for i in range(1,n+1):
    c,m,e = list(map(int,input().split()))
    x = [c+m+e,c,i]
    res.append(x)
res.sort(lambda res:(-res[0],-res[1],res[2]))
for i in range(5):
    print('%d %d' % (res[i][2],res[i][0]))

# 学生按成绩排名由大到小,成绩相同按姓名字母序升序,之后按照id升序
# aa 100 1
# bb 100 2
# c 100 3
# d 90 4
# aa 100 5
n = int(input())
a = []
for i in range(n):
    name,score,i = list(input().split())
    x = [name,int(score),int(i)]
    a.append(x)
a.sort(lambda a:(-a[1],a[0],a[2]))
for i in range(n):
    print('%s %d %d' %(a[i][0],a[i][1],a[i][2]))

最小生成树

import math
n,m = list(map(int,input().split()))
e = []
for i in range(m):
    x = list(map(int,input().split()))
    e.append(x)
def find(x):
    if f[x]==x:
        return x
    else:
        f[x]=find(f[x])
    return f[x]
f = [0 for i in range(n+1)]
inf = 100000000000000
def kruskal():
    e.sort(lambda e:e[2])
    for i in range(n+1):
        f[i]=i
    res=0
    cnt=0
    for i in range(m):
        a=e[i][0]
        b=e[i][1]
        w=e[i][2]
        a=find(a)
        b=find(b)
        if a!=b:
            f[a]=b
            res+=w
            cnt+=1
    if cnt<n-1:
        return inf
    return res
ans = kruskal()
if ans!=inf:
    print(ans)
else:
    print('impossible')

素数筛

import bisect
n = int(input())
prime = []
N = 1000000
st = [0 for i in range(N+1)]
for i in range(2,N+1):
    if st[i]==1:
        continue
    prime.append(i)
    for j in range(i,N+1,i):
        st[j]=1
p = bisect.bisect_right(prime,n)
print(p)
        

最短路

Bell-man

n,m = list(map(int,input().split()))
e = []
for i in range(m):
    x = list(map(int,input().split()))
    e.append(x)
e.sort(lambda e:e[2])
inf = 1000000000
dist = [inf for i in range(1500)]
dist[1] = 0
for i in range(n):
    for j in range(m):
        a = e[j][0]
        b = e[j][1]
        w = e[j][2]
        if dist[b]>dist[a]+w:
            dist[b]=dist[a]+w
if dist[n]==inf:
    print(-1)
else:
    print(dist[n])

dijkstra

n, m = map(int, input().split())
maxdist = float("inf")
g = [[maxdist] * (n+1) for _ in range(n+1)] # 由于是密集图,m>>n,因此用邻接矩阵来存储,g[x][y]表示x指向y的距离
d = [maxdist] * (n+1) # 存储每个点距离起点的距离,初始化为距离最大,d[1]=0
st = [False] * (n+1) # 判断某一点的最短距离是否已经确定,False表示未确定,True表示确定

def dijkstra():
    d[1] = 0
    for i in range(1, n+1): # 因为要确定n个点的最短路,因此要循环n次
        t = -1
        for j in range(1, n+1): # 每次找到还未确定最短路的点中距离起点最短的点t
            if not st[j] and (t==-1 or d[t]>d[j]):
                t = j
        st[t] = True
        for j in range(1, n+1): # 用t来更新t所指向的点的距离
            d[j] = min(d[j], d[t] + g[t][j])
    if d[n] >= maxdist:
        return -1
    else:
        return d[n]

for _ in range(m):
    x, y, z = map(int, input().split())
    g[x][y] = min(g[x][y], z) # 当出现重边时,只需取两个距离中的最小值
print(dijkstra())

你可能感兴趣的:(比赛,python,蓝桥杯,开发语言)