title: 2023ICPC济南站VP补题记录(第48届)
date: 2024-01-18 12:16:23
mathjax: true
tags: XCPC
categories: Algorithm
本人是主要Python竞赛,补题代码实现一般用python,在codeforces中,由于没未其他语言开另外时限,python提交无法ac的情况下补题给出C++实现,按难度排序。
假设 f ( x ) f(x) f(x) 是正整数 x x x 的十进制表示中的最大位数。例如, f ( 4523 ) = 5 f(4523) = 5 f(4523)=5 和 f ( 1001 ) = 1 f(1001) = 1 f(1001)=1。
给定四个整数 l a l_a la, r a r_a ra, l b l_b lb 和 r b r_b rb 其中 l a ≤ r a l_a \le r_a la≤ra 并且 l b ≤ r b l_b \le r_b lb≤rb, 计算 f ( a + b ) f(a + b) f(a+b) 的最大值( l a ≤ a ≤ r a l_a \le a \le r_a la≤a≤ra , , , l b ≤ b ≤ r b l_b \le b \le r_b lb≤b≤rb).
这是一道签到题,比较简单直接上代码吧~
import sys
input = sys.stdin.readline
def solve():
la,ra,lb,rb = map(int, input().split())
l = la+lb
r = ra + rb
ans = 0
if r - l > 10:
ans = 9
else:
for i in range(l,r+1):
x = i
while x:
ans = max(x%10,ans)
x //= 10
print(ans)
for _ in range(int(input())):
solve()
在学习了 2021 国际大学生程序设计竞赛亚洲区域赛南京站的《Paimon Sorting》一题中奇怪的排序算法 后,小青鱼想到了如下的一个问题。 给定序列 a 1 , a 2 , ⋅ ⋅ ⋅ , a n a_1, a_2, · · · , a_n a1,a2,⋅⋅⋅,an 表示一个 n 的排列,您需要将该排列按升序排序,为此可以执行以下操作至多 n / 2 {n}/{2} n/2 次:选择两个下标 l 和 r 满足 1 ≤ l < r ≤ n 1 ≤ l < r ≤ n 1≤l<r≤n以及 a l > a r a_l > a_r al>ar,将 a l , a l + 1 , ⋅ ⋅ ⋅ , a r a_l , a_l+1, · · · , a_r al,al+1,⋅⋅⋅,ar 按升序进行排序。 请回忆:一个 n 的排列是一个长度为 n 的序列,每个从 1 到 n(含两端)的整数在其中都恰好出现一 次。
这题等待队友写题解喽~
import sys
input = sys.stdin.readline
def solve():
n = int(input())
a = list(map(int, input().split()))
ls = []
for i in range(n):
start = i
end = i
for j in range(i+1, n):
if a[start] > a[j]:
end = j
if start != end:
ls.append((start + 1, end + 1))
a[start:end+1] = sorted(a[start:end+1])
print(len(ls))
for l, r in ls: print(l, r)
for _ in range(int(input())):
solve()
多头杯(Multi-Heads Cup),简称 MHC,是为拥有**多头的参赛者举办的世界性编程比赛。大赛总裁判长小青鱼正在考虑为每位参赛者设计一个识别号码。
"就这样吧,"小青鱼想,"我们用一些括号序列吧!"他给每个参赛者分配了一个独一无二的平衡括号序列,括号有两种–圆括号(也叫小括号)和方括号。为了确保大家理解平衡括号序列的概念,小青鱼准备了一份平衡括号序列的正式定义:
例如,“()”、“[()]“和”[()]() “是平衡括号序列,但”)(”、"[(]) “和”[) "不是。
对于多头参与者来说,记忆括号序列并不是一件难事。然而,挑战在于他们的独特能力:由于他们的头数太多,他们无法辨别每个括号的方向!因此,与原来的平衡括号序列相比,他们在记忆序列时可能会改变一些括号的方向。例如,括号序列"[()]() “可能会被记忆成”])) “或”]()])"。幸运的是,括号的类型保证保持不变。
比赛当天,当小青鱼收到每位参赛者的括号序列时,一个问题出现了:能否唯一地推导出原始括号序列?换句话说,小青鱼需要确定所提供的括号序列是否正好映射到一个平衡的括号序列。
请帮助 "小青鱼 "完成这项任务,这样我们的多头朋友就能参加比赛了!
这道题很容易让我们想到栈的经典问题括号匹配,但其实感觉和这题没啥关系,主要还是考思维,我们其实很容易想到有三个连续的相同种类括号那么答案必然是 N o No No,比如 ( ) ( X ) ()(X) ()(X)必然可以条成 ( ( ) X ) (()X) (()X) 而 ( X ) ( ) (X)() (X)()这种同理。
那么我们现在考虑两个连续的相同种类阔号:假设只有一个 ( ) 或 [ ] ()或[] ()或[],其他全是交替,是满足条件的,如果有两个呢,不妨设为小括号,中括号同理,形如: A ( ) B ( ) C A()B()C A()B()C 这中类型。我们会发现只有 ( ) [ ( ) ] ()[()] ()[()] 满足条件。
综上所述,一个括号序列合法,当且仅当其不存在长度 ≥ 3 ≥3 ≥3 的连续段,且存在不超过 2 个长度 ≥ 2 ≥2 ≥2 的连续段。
import sys
input = sys.stdin.readline
def solve():
s = input().strip()
cnt = 0
s1 = {'(',')'}
for i in range(len(s)-1):
if (s[i] in s1 and s[i+1] in s1) or (s[i] not in s1 and s[i+1] not in s1):
cnt += 1
if cnt >= 3:
print("No")
return
print("Yes")
for _ in range(int(input())):
solve()
在学习了理查德-彭(Richard Peng)和桑托什-文帕拉(Santosh Vempala)的论文《比矩阵乘法更快地解决稀疏线性系统》(Solving Sparse Linear Systems Faster than Matrix Multiplication)后,小青鱼对任何稀疏的东西都很着迷。例如,稀疏矩阵。这里,稀疏矩阵指的是零元素的数量远远多于非零元素数量的矩阵。现在,小青鱼想出了一个关于二进制稀疏矩阵的问题,他想让你试着解决这个问题。
给定一个有 r r r 行和 c c c 列的二进制矩阵(只包含 0 0 0 s 和 1 1 1 s 的矩阵),你可以选择是否反转每一行。求在每列最多有一个 1 1 1 的情况下,有多少种方法可以选择一组行来反转(允许不选择任何行)。如果在其中一种方法中选择了一行,而在另一种方法中没有选择,那么这两种方法就被认为是不同的。
我们所说的颠倒行是指这样:让 i i i -th行上的元素从第一列到最后一列都是 b i , 1 , b i , 2 , ⋯ , b i , c b_{i,1}, b_{i, 2}, \cdots, b_{i, c} bi,1,bi,2,⋯,bi,c 。如果把 i i i (th)行颠倒过来,它就变成了 b i , c , b i , c − 1 , ⋯ , b i , 1 b_{i, c}, b_{i, c - 1}, \cdots, b_{i, 1} bi,c,bi,c−1,⋯,bi,1。
如果第 j j j 列和第 ( m − j + 1 ) (m − j + 1) (m−j+1) 总共的 1 的数量超过了两个, 显然无解。否则假设这两个 1 位于第 i i i 行和第 i ′ i' i′ 行,有两种 情况: 两个 1 处于同一列,则 i i i 和 i ′ i' i′ 的选择情况是相反的。 两个 1 处于不同列,则 i i i 和 i ′ i' i′ 的选择情况是相同的。 给定相同相反关系,求方案数是一个经典问题,可以通过建图来维护,当然我们也可以通过扩展域并查集来求。
import sys
input = sys.stdin.readline
mod = 1000000007
def solve():
def find(x):
if fa[x] == x: return x
fa[x] = find(fa[x])
return fa[x]
n,m = map(int, input().split())
fa = [i for i in range(n+n)]
ls = [list(input().strip()) for _ in range(n)]
for i in range(m//2+1):
l1, l2 = [], []
if i == m-i-1:
for j in range(n):
if ls[j][i] == '1': l1.append(j)
if len(l1) > 1:
print(0)
return
else:
for j in range(n):
if ls[j][i] == '1': l1.append(j)
if ls[j][m - i - 1] == '1': l2.append(j)
if len(l1)+len(l2) > 2:
print(0)
return
if l1 and l2:
pa,pb = find(l1[0]),find(l2[0])
fa[pa] = pb
pa,pb = find(l1[0]+n),find(l2[0]+n)
fa[pa] = pb
elif len(l1) == 2:
pa,pb = find(l1[0]),find(l1[1]+n)
fa[pa] = pb
pa,pb = find(l1[1]),find(l1[0]+n)
fa[pa] = pb
elif len(l2) == 2:
pa,pb = find(l2[0]),find(l2[1]+n)
fa[pa] = pb
pa,pb = find(l2[1]),find(l2[0]+n)
fa[pa] = pb
for i in range(n):
if find(i) == find(i+n):
print(0)
return
print(pow(2,len(set(fa))//2,mod))
for _ in range(int(input())):
solve()
import sys
from collections import deque
input = sys.stdin.readline
mod = 1000000007
def solve():
def bfs(x):
q = deque()
q.append(x)
while q:
x = q.popleft()
if color[x]: continue
color[x] = cnt
for y in g[x]:
if not color[y]: q.append(y)
n, m = map(int, input().split())
ls = [input().strip() for _ in range(n)]
g = [[] for i in range(n + n)]
for i in range(m//2+1):
j = m - i - 1
l1, l2 = [], []
for k in range(n):
if ls[k][i] == '1': l1.append(k)
if ls[k][j] == '1': l2.append(k)
if len(l1) + len(l2) <= 1: continue
if i == j:
if len(l1) >= 2:
print(0)
return
else:
if len(l1)+len(l2) > 2:
print(0)
return
for a in l1:
for b in l2:
g[a].append(b)
g[b].append(a)
g[a + n].append(b + n)
g[b + n].append(a + n)
for a in range(len(l1)):
for b in range(len(l1)):
if a == b: continue
g[l1[a]].append(l1[b] + n)
g[l1[b] + n].append(l1[a])
g[l1[b]].append(l1[a] + n)
g[l1[a] + n].append(l1[b])
for a in range(len(l2)):
for b in range(len(l2)):
if a == b: continue
g[l2[a]].append(l2[b] + n)
g[l2[b] + n].append(l2[a])
g[l2[b]].append(l2[a] + n)
g[l2[a] + n].append(l2[b])
cnt = 0
color = [0] * (n + n)
for i in range(n + n):
if not color[i]:
cnt += 1
bfs(i)
for i in range(n):
if color[i] == color[i + n]:
print(0)
return
print(pow(2, cnt // 2, mod))
for _ in range(int(input())):
solve()