[toc]

A 穿越时空之门

特别要注意python整除是//

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cnt = 0
for i in range(1,2025):
B = i
cntB = 0
while B:
cntB += B%2
B//=2
BB = i
cntBB = 0
while BB:
cntBB += BB %4
BB//=4
if cntB == cntBB:
print(i)
cnt+=1
print(cnt)

B 数字串个数

1
2
3
4
mod = 10**9 + 7

x = (9**10000 - 2*8**10000 + 7**10000 )% mod
print(x)

C 连连看

我的题解

对一半,其余超时超时,暴力枚举对角线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from collections import deque
n , m = map(int , input().split())

arr = []

for i in range(n):
arr.append(list(map(int , input().split())))

xway = [-1,-1,1,1]
yway = [-1,1,-1,1]


cnt = 0
for i in range(n):
for j in range(m):
for way in range(4):
x = i + xway[way]
y = j + yway[way]
while 0<=x<n and 0<=y<m:
if arr[x][y] == arr[i][j]:
cnt+=1
x+= xway[way]
y+= yway[way]

print(cnt)

正确解法

类似于八皇后问题,取主对角线为i-j+1005,副对角线为i+j

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys
n , m = map(int , input().split())

arr = []
zhu = [[0]*2050 for _ in range(2025)]
fu = [[0]*2050 for _ in range(2025)]


for i in range(n):
arr.append(list(map(int,input().split())))
ans = 0
for i in range(n):
for j in range(m):
ans += zhu[i-j+1005][arr[i][j]] + fu[i+j][arr[i][j]]
zhu[i-j+1005][arr[i][j]]+= 1
fu[i+j][arr[i][j]]+= 1

print(ans*2)

D 神奇的闹钟

使用datetime库解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from datetime import datetime, timedelta


st = datetime(1970,1,1)
#print(st)

n = int(input())

for i in range(n):
ymd, hms, m = input().split()
st = datetime(1970,1,1)
#print(st)
m = int(m)

tt = datetime.fromisoformat(ymd+" "+hms)
#print(tt)
d = timedelta(minutes=m)
#print(d)
while st<tt:
st+=d
print(st-d)

E 蓝桥村的真相

暴力枚举然后找规律

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

def check(ll):
cnt = 0
for i in range(len(ll)):
tmp = ll[i]
leng = len(ll[i])
flag = False
for j in range(leng*100):
pos = j%leng
if tmp[pos] == 1:
if tmp[(pos+1)%leng] == 1 and tmp[(pos+2)%leng] == 1:
flag = True
break
if tmp[(pos+1)%leng] ==0 and tmp[(pos+2)%leng] == 0:
flag = True
break
if tmp[pos] == 0:
if tmp[(pos+1)%leng] == 1 and tmp[(pos+2)%leng] == 0:
flag = True
break
if tmp[(pos+1)%leng] ==0 and tmp[(pos+2)%leng] == 1:
flag = True
break
if flag:
continue

for j in range(leng):
if tmp[j] == 0:
cnt += 1
#print(cnt)
return cnt

def dfs(path):
if len(path) == n:
ll.append(path.copy()) # 传入副本而不是地址
return
for i in range(0,2):
path.append(i)
#print(path)
dfs(path)
path.pop()

for i in range(1,10):
n = i
ll = []
dfs([])
#print(ll)
print(check(ll))


F 魔法巡游

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import os
import sys

n = int(input())
a = [0] + list(map(int, input().split()))
b = [0] + list(map(int, input().split()))

inf = float('inf')


dp1 = [[-inf]*3 for _ in range(n+1)]
dp2 = [[-inf]*3 for _ in range(n+1)]

# dp1[0] = [0]*3 dp1不能初始化为0,因为小桥不是先手,无法从dp1转移
dp2[0] = [0]*3


for i in range(1,n+1):
len = -inf
x = a[i]
e = set()

dp1[i] = dp1[i-1].copy()
for j in str(x):
if j == '0':
e.add(0)
len = max(len,dp2[i-1][0])
if j == '2':
e.add(1)
len = max(len,dp2[i-1][1])
if j == '4':
e.add(2)
len = max(len,dp2[i-1][2])
for k in e:
dp1[i][k] = max(dp1[i][k],len+1)

len = -inf
e = set()

x = b[i]
dp2[i] = dp2[i-1].copy()
for j in str(x):
if j == '0':
e.add(0)
len = max(len,dp1[i-1][0])
if j == '2':
e.add(1)
len = max(len,dp1[i-1][1])
if j == '4':
e.add(2)
len = max(len,dp1[i-1][2])

for k in e:
dp2[i][k] = max(dp2[i][k],len+1)

if n == 1:
print(1)
else:
print(max(max(dp1[-1]),max(dp2[-1])))

H纯职业小组

参考题解

有思路但是写不出来

第十五届蓝桥杯PythonB组H题纯职业小组题解 - AcWing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
T = int(input())
for _ in range(T):
n, k = map(int, input().split())
h = {}
for i in range(n):
a, b = map(int, input().split())
if a not in h:
h[a] = 0
h[a] += b

b = []
for x in h:
b.append(h[x])

n = len(b)

cnt = 0
res = 0
for i in range(n): # 去除为2的小组
cnt += b[i] // 3
u = min(b[i], 2)
b[i] -= u
res += u

if cnt < k: #无法构成
print(-1)
continue

c1, c2, c3 = 0, 0, 0 #记录能组成1,2,3小组的个数
for x in b:
c3 += x // 3 #记录c3小组个数
x %= 3
if x == 1:
c1 += 1
elif x == 2:
c2 += 1

# k为1时,再取一个即可
k -= 1
res += 1

# 优先取3的组,
v = min(k, c3)
k -= v
c3 -= v
res += v * 3

v = min(k, c2)
k -= v
c2 -= v
res += v * 2

v = min(k, c1)
k -= v
c1 -= v
res += v * 1

print(res)