Codeforces Round 923 (Div. 3)(A~E)python

本文介绍了五道Codeforces问题,涉及贪心算法、字符串处理、数据结构(如前缀和)以及构造满足特定条件的数组。问题C和D展示了如何利用贪心策略解决数字组合问题,而A、B、E则涉及字符串操作和构建特定模式的数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Make it White

Problem - A - Codeforces

签到题,字符串

1542a4f15be54bbebf0c1d575d8c12ea.png

找到最左侧和最右侧黑色位置,将中间的变成白色即可

t = int(input())
for _ in range(t):
    n = int(input())
    s = input()
    res = s.rfind("B")-s.find("B")+1
    print(res)

 

B. Following the String

Problem - B - Codeforces

贪心,构造

212adf4a241c48078954687930d9c859.png

通过存储每个位置该字母此前出现次数的数组构造字符串,例如为0时,说明未出现过该字母,否则之前一定出现过,

使用数组分别存储每种数量当前用到的字母,构造字符串时,优先使用字母表中靠前的字母,下次再出现该数量时使用下一个字母,

这样可以保证每种数量都只会使用一个字母一次,且在之前出现过(例如为1时,前面一定有更多的0)

t = int(input())
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))
    now = [0]*(n+1)
    res = ""
    for ai in a:
        res += chr(ord("a")+now[ai])
        now[ai] += 1
    print(res)

 

C. Choose the Different Ones!

Problem - C - Codeforces

贪心,数学

b2a50cd1c6e04d9aa6af4960f1ecde91.png

题目要求每个数组中取k//2个元素,恰好构造出1到k所有的数字

将两数组去重排序,依次寻找1到k的数字,并记录a独有的,b独有的和两人都有的

若有数组未找到则构造失败,否则看a,b独有的中数量较小的那个能否使用公共的凑出k//2个元素,若能凑出,则恰好可以构造

def check():
    global a, b
    i, j, now = 0, 0, 1
    only_a, only_b, same = 0, 0, 0
    while now <= k:
        if (i < n and a[i] == now) and (j < m and b[j] == now):
            same += 1
            i += 1
            j += 1
        elif i < n and a[i] == now:
            only_a += 1
            i += 1
        elif j < m and b[j] == now:
            only_b += 1
            j += 1
        else:
            return False
        now += 1
    return min(only_a, only_b) + same >= k//2


t = int(input())
for _ in range(t):
    n, m, k = map(int, input().split())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    a, b = list(set(a)), list(set(b))
    a.sort(), b.sort()
    n, m = len(a), len(b)
    if check():
        print("YES")
    else:
        print("NO")

 

D. Find the Different Ones!

Problem - D - Codeforces

贪心,数据结构,前缀和

b3e0971484ce40739c04d3ca93046018.png

要求找到每个区间一对不相同的元素

对于每个l,只要找到右侧第一个不同的元素即可,当r大于该元素时,就一定可以找到一对不同的元素

将相邻重复元素合并,计算相邻数字出现次数的前缀和,那么每种数字右侧第一个不同的数字就是该元素前缀和表示的下一个元素,用列表存储代表该元素的下标

当r小于该元素,则一定找不到不同的元素,否则打印l和第一个不同的元素即可

t = int(input())
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))
    q = int(input())
    lr = [list(map(int, input().split())) for _ in range(q)]
    s, st = [0], [-1]*n
    i, idx = 0, 1
    while i < n:
        num = 1
        now = a[i]
        st[i] = idx
        while i+1 < n and a[i+1] == now:
            i += 1
            num += 1
            st[i] = idx
        s.append(s[-1]+num)
        idx += 1
        i += 1
    for l, r in lr:
        if r-1 >= s[st[l-1]]:
            print(l, s[st[l-1]]+1)
        else:
            print("-1 -1")
    print()

 

E. Klever Permutation

Problem - E - Codeforces

构造

068fc813aeb64f40b1c601be8f0b3c00.png

构造一个数组,使任意两个长度为k的区间中元素的总和差距不超过1

纯纯看样例,k个一组,l,r表示当前在一组中的左右位置,ma,mi表示当前要构造的最大元素和最小元素

大的先在每组的l递减构造,小的再在每组的r递增构造,更新l,r,然后每过一轮各自交换一次l和r,直到每个数字都用完为止

t = int(input())
for _ in range(t):
    n, k = map(int, input().split())
    res = [0]*(n+1)
    ma, mi = n, 1
    l, r = 1, k
    mami, lr_ma, lr_mi = 0, 0, 1
    while mi <= ma:
        if mami == 0:
            if lr_ma == 0:
                j = l
                l += 1
            else:
                j = r
                r -= 1
            while j <= n:
                res[j] = ma
                ma -= 1
                j += k
            lr_ma = (lr_ma + 1) % 2
        else:
            if lr_mi == 0:
                j = l
                l += 1
            else:
                j = r
                r -= 1
            while j <= n:
                res[j] = mi
                mi += 1
                j += k
            lr_mi = (lr_mi + 1) % 2
        mami = (mami + 1) % 2
    for i in range(1, n+1):
        print(res[i], end=" ")
    print()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值