A. ICPC Regionals

按题意判断即可。

注意 可以用 计算。

时间复杂度

n, k = map(int, input().split())
t = (n+9)//10
if k <= t:
    print("Gold Medal")
elif k <= 3*t:
    print("Silver Medal")
elif k <= 6*t:
    print("Bronze Medal")
else:
    print("Da Tie")

B.Card Game

不难发现,把把牌合并要不一张都不和,此时为原来的最大值,要不就全部和,此时为

答案即为

时间复杂度

for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    print(max(max(a), n))

C. Palindrome Coloring

如果原来就是一个回文串,则答案为

否则我们可以先选择所有的 ,再选择所有的 ,两个子序列一定是回文串,答案为

时间复杂度

for _ in range(int(input())):
    s = input().strip()
    if s[::-1] == s:
        print(1)
    else:
        print(2)

D.Digital Pairing

题意即为选择 个数字,使其按位与最大。

已知答案为 ,则一定有至少 个数字 满足

不难想到可以从大到小按位枚举,如果当前答案存在至少 个满足 ,则可以更新答案。

时间复杂度

for _ in range(int(input())):
    n = int(input())
    a = [0] + list(map(int, input().split()))
    ans = 0
    for i in range(60, -1, -1):
        now = ans | (1<<i)
        cnt = 0
        for j in range(1, 2*n+1):
            if (a[j] & now) == now:
                cnt += 1
        if cnt >= n:
            ans = now
    print(ans)

E.Beautiful Sequence

不难想到枚举 gcd,使用容斥处理。

如果没有数组的 ⁡gcd 不存在于数组中的条件,我们只需要从打到小枚举 gcd,则所有是当前 gcd 倍数的数字,任选其中的一部分的 gcd 是枚举的 gcd 或者其倍数。

我们只需要减去是当前枚举的 gcd 的倍数的情况就能得出答案。

回到本题,不难想到我们只需要在统计单的时候,减去包含的枚举的 gcd 这个数字的情况即可。

时间复杂度

from collections import Counter
MOD = 998244353
for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    memo = Counter(a)
    cnt = [0 for i in range(n+1)]
    for i in range(1, n+1):
        for j in range(i, n+1, i):
            cnt[i] += memo[j]
    ans = 0
    res = [0 for i in range(n+1)] # res 即为 gcd 为 d 的子序列个数(没有限制条件)
    for i in range(n, 0, -1):
        t = cnt[i] - memo[i]
        tot = (pow(2, t, MOD) - 1)%MOD
        for j in range(2*i, n+1, i):
            tot = (tot - res[j] + MOD)%MOD
        tot2 = (pow(2, cnt[i], MOD) - 1)%MOD
        for j in range(2*i, n+1, i):
            tot2 = (tot2 - res[j] + MOD)%MOD
        res[i] = tot2
        ans = (ans + tot)%MOD
    print(ans)

F.Bracket Counting

经典状压 dp(

首先不难发现,所有字符串中的左右括号数量之和必须相等。

一个字符串要能够接到现在的字符串上去,当期仅当对于任意位置,右括号的数量小于左括号的数量。

所以,我们处理每个字符串余下的没有匹配的括号的数量 ,以及右括号比左括号少的最多的数量

状压 dp 时,如果当前的字符串的 不小于当前的枚举的字符串 ,则我们可以把字符串拼接上去,否则不能。

时间复杂度

MOD = 10**9 + 7
for _ in range(int(input())):
    n = int(input())
    ss = [input() for i in range(n)]
    
    k = [0 for i in range(n)]
    t = [0 for i in range(n)]
    tot = 0
    for i in range(n):
        s = ss[i]
        now = 0
        mi = 10**9
        for ch in s:
            if ch == '(':
                now += 1
            else:
                now -= 1
            mi = min(now, mi)
        k[i] = now
        t[i] = max(0, -mi)
        tot += now
            
    if tot != 0:
        print(0)
        continue
    
    su = [0 for i in range(1<<n)]
    dp = [0 for i in range(1<<n)]
    dp[0] = 1
    for mask in range(1, 1<<n):
        for i in range(n):
            if mask >>i & 1:
                su[mask] += k[i]
    for mask in range(1<<n):
        if dp[mask] == 0:
            continue
        now = su[mask]
        for j in range(n):
            if mask >> j & 1 or now < t[j]:
                continue
            dp[mask|(1<<j)] = (dp[mask|(1<<j)] + dp[mask])%MOD
    print(dp[(1<<n)-1]%MOD)