输入与输出
输入
数组输入:
可以提前定义
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)
a = 2
b = 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
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]
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]
print(bisect.bisect_left(a,5))
print(bisect.bisect_left(a,4))
print(bisect.bisect_right(a,4))
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 个用空格隔开的数字,每个数字都在 0 到 100 之间,第 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 = []
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]))
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())