Codeforces Round 960 (Div. 2) (A~C) python

A. Submission Bait

https://codeforces.com/contest/1990/problem/A

博弈论

先选最大的有奇数个数量的数字,这样能保证对手后面怎么选,都有相同的可选

看有没有出现奇数个的元素即可

from collections import Counter


def check():
    for i in c.values():
        if i % 2 == 1:
            return True
    return False


t = int(input())
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))
    c = Counter(a)
    if check():
        print("YES")
    else:
        print("NO")

B. Array Craft

https://codeforces.com/contest/1990/problem/B

构造

题意,给定y<x,构造a数组,使从开头加到ax是最大的前缀和,从ay加到结尾是最大的后缀,a只能使用1和-1

发现前缀和后缀中间一定有重合的部分,将该部分设为1,这部分和至少为2,然后保证不会有更短的最大前缀,最大后缀,从y-1往前-1和1交替,从x+1往后-1和1交替,每两个可以抵消

t = int(input())
for _ in range(t):
    n, x, y = map(int, input().split())
    a = [0]*n
    for i in range(y-1, x):
        a[i] = 1
    now = -1
    for i in range(x, n):
        a[i] = now
        if now == 1:
            now = -1
        else:
            now = 1
    now = -1
    for i in range(y-2, -1, -1):
        a[i] = now
        if now == 1:
            now = -1
        else:
            now = 1
    for ai in a:
        print(ai, end=" ")
    print()

 

C. Mad MAD Sum

https://codeforces.com/contest/1990/problem/C

题意,每次答案加上a数组的总和,每一次迭代将a每个元素更新为数组上一次该索引前出现两个以上的最大的数,直到a中所有元素都为0

思路:可以发现一个数出现两次后,若未出现更大的,后面都是以该数字为结果,且每次迭代,除最后一个最大值个数会减一,其他的数字只要仍有两个,下一次出现的数目不会改变,由此想到可以单独计算每个数字的贡献

存储每个数字在第一次迭代后的状态,每个元素计算作为最大值的左右位置和上一个最大值,

如果有数字只出现了一次,下一次迭代将不会出现,这时这个数字在之后的位置就会被上个出现两次以上的最大值替代,这里用dp思想,若上个最大值仍只出现一次,直接用上上个最大值即可

最后用等差数列计一下数,只出现一次的,计算下替代的元素

 

def cal(be, ct):
    return (be+be-ct+1)*ct//2


t = int(input())
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))
    ct = [0]*(n+1)
    lr = [[-1, -1, 0] for _ in range(n+1)]
    ma = 0
    for i in range(n):
        if ct[a[i]] == 0:
            ct[a[i]] += 1
        elif ct[a[i]] == 1:
            ct[a[i]] += 1
            if a[i] > ma:
                if lr[ma][1] != lr[ma][0]:
                    las = ma
                else:
                    las = lr[ma][2]
                lr[a[i]] = [i, i, las]
                ma = a[i]
        lr[ma][1] = i
    res = sum(a)
    for ma in range(1, n+1):
        l, r, las = lr[ma]
        if l == -1 or r == -1:
            continue
        elif l == r:
            res += ma+las*(n-l-1)
            # print(ma, las, (n-l-1), las*(n-l-1), ma+las*(n-l-1))
        else:
            res += cal(n-l, r-l+1)*ma
            # print(ma, cal(n-l, r-l+1), cal(n-l, r-l+1)*ma)
    # print(lr)
    print(res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值